-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add percent column component using intl formatter (#622)
* feat: add percent column component using intl formatter * fix: change title to container * fix: useLocale import from react-rainbow-component * feat: add cellAlignment prop Co-authored-by: Jose Leandro Torres <jtorressicilia@gmail.com>
- Loading branch information
1 parent
1bdec4f
commit e5bfe3a
Showing
11 changed files
with
284 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Meta, Story, Preview, Props } from '@storybook/addon-docs/blocks'; | ||
import PercentColumn from '../../src/components/PercentColumn'; | ||
import * as stories from '../stories/PercentColumn.story.js'; | ||
|
||
<Meta title="Modules/Listview/Components/PercentColumn" component={PercentColumn} /> | ||
|
||
# Overview | ||
|
||
`PercentColumn` is a column that renders the percent number passed as value. | ||
|
||
### This is an example with the PercentColumn. | ||
|
||
<Preview> | ||
<Story name="PercentColumn">{stories.percentColumn()}</Story> | ||
</Preview> | ||
|
||
# Component props | ||
|
||
<Props of={PercentColumn} /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import React from 'react'; | ||
import styled from 'styled-components'; | ||
import { Table, Column, Application } from 'react-rainbow-components'; | ||
import PercentColumn from '../../src/components/PercentColumn'; | ||
import ColoredStatusColumn from '../../src/components/ColoredStatusColumn'; | ||
|
||
const initialData = [ | ||
{ | ||
name: 'Carls Smith', | ||
status: 'canceled', | ||
company: 'Google', | ||
percent: 0.1, | ||
createdAt: '09/06/2020 09:00 AM', | ||
}, | ||
{ | ||
name: 'John Snow', | ||
status: 'delivered', | ||
company: 'Google', | ||
percent: 0.0025, | ||
createdAt: '09/06/2020 09:00 AM', | ||
}, | ||
{ | ||
name: 'Anna Adams', | ||
status: 'pending', | ||
company: 'Google', | ||
percent: 0.3045, | ||
createdAt: '09/06/2020 09:00 AM', | ||
}, | ||
{ | ||
name: 'William Adams', | ||
status: 'arrived', | ||
company: 'Google', | ||
percent: 0, | ||
createdAt: '09/06/2020 09:00 AM', | ||
}, | ||
{ | ||
name: 'Joe Smith', | ||
status: 'arrived', | ||
company: 'Google', | ||
percent: 0.8, | ||
createdAt: '09/06/2020 09:00 AM', | ||
}, | ||
{ | ||
name: 'John Doe', | ||
status: 'arrived', | ||
company: 'Google', | ||
percent: 1, | ||
createdAt: '09/06/2020 09:00 AM', | ||
}, | ||
{ | ||
name: 'Jane Adams', | ||
status: 'arrived', | ||
company: 'Google', | ||
percent: 1.2, | ||
createdAt: '09/06/2020 09:00 AM', | ||
}, | ||
]; | ||
|
||
const Container = styled.div` | ||
padding: 2rem; | ||
`; | ||
|
||
const colors = { | ||
canceled: { backgroundColor: '#f2707a', color: 'rgba(255, 255, 255)' }, | ||
delivered: '#009900', | ||
pending: { backgroundColor: '#EBC665', color: '#fff' }, | ||
arrived: { backgroundColor: '#4dc9cb', color: '#fff' }, | ||
}; | ||
|
||
export const percentColumn = () => { | ||
return ( | ||
<Application> | ||
<Container> | ||
<Table data={initialData} keyField="id" variant="listview" showCheckboxColumn> | ||
<Column header="Created At" field="createdAt" /> | ||
<Column header="Name" field="name" /> | ||
<Column header="Company" field="company" /> | ||
<Column header="Percent" field="percent" component={PercentColumn} /> | ||
<Column | ||
header="Status" | ||
field="status" | ||
colors={colors} | ||
component={ColoredStatusColumn} | ||
/> | ||
</Table> | ||
</Container> | ||
</Application> | ||
); | ||
}; | ||
|
||
export const percentWithIntlOptionColumn = () => { | ||
return ( | ||
<Application> | ||
<Container> | ||
<Table data={initialData} keyField="id" variant="listview" showCheckboxColumn> | ||
<Column header="Created At" field="createdAt" /> | ||
<Column header="Name" field="name" /> | ||
<Column header="Company" field="company" /> | ||
<Column | ||
header="Percent" | ||
field="percent" | ||
component={PercentColumn} | ||
minimumFractionDigits={1} | ||
maximumFractionDigits={2} | ||
/> | ||
<Column | ||
header="Status" | ||
field="status" | ||
colors={colors} | ||
component={ColoredStatusColumn} | ||
/> | ||
</Table> | ||
</Container> | ||
</Application> | ||
); | ||
}; | ||
|
||
export default { | ||
title: 'Modules/Listview/Stories/PercentColumn', | ||
parameters: { | ||
viewOnGithub: { | ||
fileName: __filename, | ||
}, | ||
}, | ||
}; |
29 changes: 29 additions & 0 deletions
29
packages/listview/src/components/PercentColumn/__test__/percentColumn.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import React from 'react'; | ||
import { mount } from 'enzyme'; | ||
import PercentColumn from '../index'; | ||
import { StyledCellContainer } from '../styled'; | ||
|
||
describe('<PercentColumn />', () => { | ||
it('should render a PercentColumn with the value passed', () => { | ||
const wrapper = mount(<PercentColumn value={1} />); | ||
const output = wrapper.find(StyledCellContainer); | ||
expect(output.exists()).toBe(true); | ||
expect(output.text()).toBe('100%'); | ||
}); | ||
|
||
it('should render a PercentColumn with the value passed and intl options', () => { | ||
const wrapper = mount( | ||
<PercentColumn value={0.5025} minimumFractionDigits={1} maximumFractionDigits={2} />, | ||
); | ||
const output = wrapper.find(StyledCellContainer); | ||
expect(output.exists()).toBe(true); | ||
expect(output.text()).toBe('50.25%'); | ||
}); | ||
|
||
it('should render a center text whne cellAlignment is center', () => { | ||
const wrapper = mount(<PercentColumn value={1} cellAlignment="center" />); | ||
const output = wrapper.find(StyledCellContainer); | ||
expect(output.exists()).toBe(true); | ||
expect(output.prop('cellAlignment')).toBe('center'); | ||
}); | ||
}); |
16 changes: 16 additions & 0 deletions
16
packages/listview/src/components/PercentColumn/helpers/formatPercent.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
interface Options { | ||
minimumIntegerDigits?: number; | ||
minimumFractionDigits?: number; | ||
maximumFractionDigits?: number; | ||
minimumSignificantDigits?: number; | ||
maximumSignificantDigits?: number; | ||
} | ||
|
||
const formatPercent = (value: number, locale: string, options: Options): string => { | ||
return new Intl.NumberFormat(locale, { | ||
style: 'percent', | ||
...options, | ||
}).format(value); | ||
}; | ||
|
||
export default formatPercent; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { useLocale } from 'react-rainbow-components'; | ||
import formatPercent from './helpers/formatPercent'; | ||
import { StyledCellContainer } from './styled'; | ||
import { PercentColumnProps } from './types'; | ||
|
||
const PercentColumn: React.FC<PercentColumnProps> = (props: PercentColumnProps) => { | ||
const { value, locale: localeProp, className, style, cellAlignment, ...rest } = props; | ||
const locale = useLocale(localeProp); | ||
const content = formatPercent(value ?? 0, locale, rest); | ||
|
||
return ( | ||
<StyledCellContainer | ||
className={className} | ||
style={style} | ||
title={content} | ||
cellAlignment={cellAlignment} | ||
> | ||
{content} | ||
</StyledCellContainer> | ||
); | ||
}; | ||
|
||
PercentColumn.propTypes = { | ||
/** A number that comes from the data and is displayed in the table cell */ | ||
value: PropTypes.number, | ||
/** The PercentColumn locale. Defaults to browser's language. */ | ||
locale: PropTypes.string, | ||
/** The minimum number of integer digits to use. | ||
* A value with a smaller number of integer digits than this number will be left-padded with zeros (to the specified | ||
* length) when formatted. Possible values are from 1 to 21; The default is 1. */ | ||
minimumIntegerDigits: PropTypes.number, | ||
/** The minimum number of fraction digits to use. Possible values are from 0 to 20; | ||
* the default for percent formatting is 0; */ | ||
minimumFractionDigits: PropTypes.number, | ||
/** The maximum number of fraction digits to use. Possible values are from 0 to 20; | ||
* the default for percent formatting is the larger of minimumFractionDigits and 0. */ | ||
maximumFractionDigits: PropTypes.number, | ||
/** The minimum number of significant digits to use. Possible values are from 1 to 21; The default is 1. */ | ||
minimumSignificantDigits: PropTypes.number, | ||
/** The maximum number of significant digits to use. Possible values are from 1 to 21; The default is 21. */ | ||
maximumSignificantDigits: PropTypes.number, | ||
/** A CSS class for the outer element, in addition to the component's base classes. */ | ||
className: PropTypes.string, | ||
/** An object with custom style applied to the outer element. */ | ||
style: PropTypes.object, | ||
/** Determines the alignment of the text in each column cell. */ | ||
cellAlignment: PropTypes.oneOf(['left', 'right', 'center']), | ||
}; | ||
|
||
PercentColumn.defaultProps = { | ||
value: undefined, | ||
locale: undefined, | ||
minimumIntegerDigits: undefined, | ||
minimumFractionDigits: undefined, | ||
maximumFractionDigits: undefined, | ||
minimumSignificantDigits: undefined, | ||
maximumSignificantDigits: undefined, | ||
className: undefined, | ||
style: undefined, | ||
cellAlignment: 'right', | ||
}; | ||
|
||
export default PercentColumn; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/* eslint-disable import/prefer-default-export */ | ||
import styled from 'styled-components'; | ||
|
||
export const StyledCellContainer = styled.div<{ cellAlignment?: 'left' | 'right' | 'center' }>` | ||
padding: 0 5px; | ||
overflow: hidden; | ||
text-overflow: ellipsis; | ||
text-align: ${(props) => props.cellAlignment}; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { CSSProperties } from 'react'; | ||
|
||
export interface PercentColumnProps { | ||
value?: number; | ||
locale?: string; | ||
minimumIntegerDigits?: number; | ||
minimumFractionDigits?: number; | ||
maximumFractionDigits?: number; | ||
minimumSignificantDigits?: number; | ||
maximumSignificantDigits?: number; | ||
className?: string; | ||
style?: CSSProperties; | ||
cellAlignment?: 'left' | 'right' | 'center'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters