Skip to content

feature: Add Divider component to Wave #221

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

Merged
merged 8 commits into from
May 11, 2022
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
13 changes: 6 additions & 7 deletions .stylelintrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@
],
"rules": {
"declaration-empty-line-before": null,
"unit-whitelist": [
"rem",
"deg",
"fr",
"ms",
"%"
],
"declaration-property-unit-whitelist": {
"/.*/": ["rem", "deg", "fr", "ms", "%", "px"]
},
"declaration-property-value-blacklist": {
"/.*/": ["(\\d+[1]+px|[^1]+px)"]
},
"value-keyword-case": ["lower", { "ignoreKeywords": ["dummyValue"] }]
}
}
35 changes: 35 additions & 0 deletions src/components/Divider/Divider.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { render, screen } from '@testing-library/react';
import * as React from 'react';
import { Divider } from './Divider';

describe('Divider', () => {
it('renders a horizontal divider by default when not passing any props', () => {
render(<Divider />);
expect(screen.getByTestId('horizontal-divider')).toBeInTheDocument();
expect(screen.queryByTestId('vertical-divider')).not.toBeInTheDocument();
});

it('renders a vertical divider when passing vertical prop', () => {
render(<Divider vertical />);
expect(screen.getByTestId('vertical-divider')).toBeInTheDocument();
expect(screen.queryByTestId('horizontal-divider')).not.toBeInTheDocument();
});

it('renders horizontal divider with 1rem top and bottom offset by default', () => {
render(<Divider />);
const dividerInstance = screen.getByTestId('horizontal-divider');
const dividerStyle = window.getComputedStyle(dividerInstance);

expect(dividerStyle.marginTop).toBe('1rem');
expect(dividerStyle.marginBottom).toBe('1rem');
});

it('renders vertical divider with 1rem left and right offset by default', () => {
render(<Divider vertical />);
const dividerInstance = screen.getByTestId('vertical-divider');
const dividerStyle = window.getComputedStyle(dividerInstance);

expect(dividerStyle.marginLeft).toBe('1rem');
expect(dividerStyle.marginRight).toBe('1rem');
});
});
52 changes: 52 additions & 0 deletions src/components/Divider/Divider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react';
import styled, { StyledComponent } from 'styled-components';
import { compose, space, SpaceProps } from 'styled-system';
import { theme } from '../../essentials/theme';
import { get } from '../../utils/themeGet';

type DividerOffset = number | string;

interface DividerProps extends SpaceProps {
/**
* Set the direction of the divider to vertical
*/
vertical?: boolean;
/**
* Set offset / margin of the divider from the surrounding content
*/
offset?: DividerOffset;
}

const HorizontalLine: StyledComponent<'div', typeof theme, DividerProps, 'theme'> = styled.div.attrs({ theme })<
Pick<SpaceProps, 'my'>
>`
width: 100%;
margin-left: auto;
margin-right: auto;
border: 0;
border-top: 1px solid ${get('semanticColors.border.primary')};

${compose(space)}
`;

const VerticalLine: StyledComponent<'div', typeof theme, DividerProps, 'theme'> = styled.div.attrs({ theme })<
Pick<SpaceProps, 'mx'>
>`
display: inline-block;
width: 0.06rem;
margin-top: 0;
margin-bottom: 0;
border: 0;
border-left: 1px solid ${get('semanticColors.border.primary')};

${compose(space)}
`;

const Divider: React.FC<DividerProps> = ({ vertical = false, offset = '1rem' }: DividerProps) =>
vertical ? (
<VerticalLine mx={offset} data-testid="vertical-divider" />
) : (
<HorizontalLine my={offset} data-testid="horizontal-divider" />
);

export { Divider, DividerProps, DividerOffset };
101 changes: 101 additions & 0 deletions src/components/Divider/docs/Divider.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
name: Divider
menu: Components
route: /components/divider
---

import { Playground } from 'docz';
import { ItemWrapper } from '../../../../docs/components/ItemWrapper.ts';
import { Divider } from '../Divider.tsx';
import { WrappedHorizontalDivider, WrappedVerticalDivider, SectionPlaceholder } from './WrappedDivider.tsx';

# Divider

**Primary UI element for visually separating content**

Renders a divider UI component: horizontal or vertical line that visually separates two pieces of data, content or UI.
<br/>

### Default Behaviour
The horizontal divider takes up the full available width and the vertical divider takes up the full available height.

The horizontal divider is rendered by default. Set **vertical** prop to `true` to change the divider orientation.
<br/>

### Divider vs Border
The default color of Divider is **$border.primary** (#C6CDD4), however...

**Divider is NOT a border, and should not be used as such. Please do not use this component as a border for elements.**

Divider is naturally expected to have a certain offset from the elements it is 'dividing' or separating.
<br/>

### Style Props
The Divider has the following design props:
- **offset** - set the divider offset from the content it is separating (uses _mx_, _my_ styled system props)
<br/>
<br/>

## Usage

### Horizontal (with default offset)

<ItemWrapper>
<WrappedHorizontalDivider offset='1rem' />
</ItemWrapper>

```jsx
<Divider />
```
<br/>

### Horizontal (without offset)

<ItemWrapper>
<WrappedHorizontalDivider offset={0} />
</ItemWrapper>

```jsx
<Divider offset={0} />
```
<br/>

### Vertical (with default offset)

<ItemWrapper>
<WrappedVerticalDivider offset='1rem' />
</ItemWrapper>

```jsx
<Divider vertical />
```
<br/>

### Vertical (without offset)

<ItemWrapper>
<WrappedVerticalDivider offset={0} />
</ItemWrapper>

```jsx
<Divider vertical />
```
<br/>

# Playground

<Playground>
<section>Section 1</section>
<Divider />
<section>Section 2</section>
</Playground>

<Playground>
{/* We need the row flow to see vertical divider */}
<div style={{ display: 'flex' }}>
<SectionPlaceholder>Section 1</SectionPlaceholder>
<Divider vertical />
<SectionPlaceholder>Section 2</SectionPlaceholder>
</div>
</Playground>

45 changes: 45 additions & 0 deletions src/components/Divider/docs/WrappedDivider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import styled from 'styled-components';
import { Divider } from '../Divider';
import type DividerOffset from '../Divider';

const DividerWrapper = styled.div`
height: auto;
display: flex;
width: 100%;
`;

const DividerColumnWrapper = styled(DividerWrapper)`
flex-direction: column;
`;

const DividerSideElement = styled.div`
height: auto;
padding: 4;
`;

const SectionPlaceholder = styled.div`
flex: 1;
height: '200px';
border: 1px black solid;
text-align: center;
padding: 20px;
`;

const WrappedHorizontalDivider = (offset: DividerOffset): React.ReactElement => (
<DividerColumnWrapper>
<DividerSideElement>Element 1</DividerSideElement>
<Divider offset={offset} />
<DividerSideElement>Element 2</DividerSideElement>
</DividerColumnWrapper>
);

const WrappedVerticalDivider = (offset: DividerOffset): React.ReactElement => (
<DividerWrapper>
<DividerSideElement>Element 1</DividerSideElement>
<Divider vertical offset={offset} />
<DividerSideElement>Element 2</DividerSideElement>
</DividerWrapper>
);

export { WrappedHorizontalDivider, WrappedVerticalDivider, SectionPlaceholder };
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export { Tag, TagProps } from './Tag/Tag';
export { InlineSpinner, InlineSpinnerProps } from './InlineSpinner/InlineSpinner';
export { TabBar, TabBarWithLink as TabBarProps } from './TabBar/TabBar';
export { DatePicker, DateRangePicker, DateRangePickerProps, DatePickerProps } from './Datepicker';
export { Divider, DividerProps } from './Divider/Divider';
export { Tooltip, TooltipProps } from './Tooltip/Tooltip';
export { Toggle, ToggleProps } from './Toggle/Toggle';
export { Box, BoxProps } from './Box/Box';
Expand Down