Skip to content

Commit

Permalink
feat(store-ui): price range (#924)
Browse files Browse the repository at this point in the history
  • Loading branch information
emersonlaurentino authored Aug 30, 2021
1 parent 8ddad55 commit e5c5d9a
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 3 deletions.
27 changes: 27 additions & 0 deletions packages/store-ui/src/molecules/PriceRange/PriceRange.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { render } from '@testing-library/react'
import React from 'react'

import PriceRange from './PriceRange'

function formatter(price: number) {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
}).format(price)
}

const props = {
formatter,
min: 0,
max: 100,
}

describe('PriceRange', () => {
it('`data-store-price-range` is present', () => {
const { getByTestId } = render(<PriceRange {...props} />)

expect(getByTestId('store-price-range')).toHaveAttribute(
'data-store-price-range'
)
})
})
68 changes: 68 additions & 0 deletions packages/store-ui/src/molecules/PriceRange/PriceRange.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { useState } from 'react'

import type { PriceProps } from '../../atoms/Price'
import Price from '../../atoms/Price'
import type { SliderProps } from '../../atoms/Slider'
import Slider from '../../atoms/Slider'

export type PriceRangeProps = SliderProps & {
/**
* The current use case variant for prices.
*/
variant?: PriceProps['variant']
/**
* Formatter function that transforms the raw price value and render the result.
*/
formatter: PriceProps['formatter']
/**
* Returns the value of element's class content attribute.
*/
className?: string
}

const PriceRange = ({
className,
formatter,
max,
min,
onChange,
testId = 'store-price-range',
variant,
}: PriceRangeProps) => {
const [minVal, setMinVal] = useState(min)
const [maxVal, setMaxVal] = useState(max)

const handleChange: SliderProps['onChange'] = (values) => {
if (values.min !== minVal) {
setMinVal(values.min)
}

if (values.max !== maxVal) {
setMaxVal(values.max)
}

onChange?.(values)
}

return (
<div data-store-price-range data-testid={testId} className={className}>
<Slider min={min} max={max} onChange={handleChange} />
<div data-store-price-range-values>
<Price
formatter={formatter}
data-store-price-range-value="min"
value={minVal}
variant={variant}
/>
<Price
formatter={formatter}
data-store-price-range-value="max"
value={maxVal}
variant={variant}
/>
</div>
</div>
)
}

export default PriceRange
2 changes: 2 additions & 0 deletions packages/store-ui/src/molecules/PriceRange/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './PriceRange'
export type { PriceRangeProps } from './PriceRange'
28 changes: 28 additions & 0 deletions packages/store-ui/src/molecules/PriceRange/stories/PriceRange.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Story, Canvas, ArgsTable } from '@storybook/addon-docs'

import PriceRange from '../PriceRange'

# PriceRange

<Canvas>
<Story id="molecules-price-range--price-range" />
</Canvas>

# Props

<ArgsTable of={PriceRange} />

# CSS Selectors

```css
[data-store-price-range] {
}
[data-store-price-range-values] {
}
[data-store-price-range-value='(min|max)'] {
}
```

# TODO

- [ ] More test cases
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { Meta, Story } from '@storybook/react'
import React from 'react'

import type { ComponentArgTypes } from '../../../typings/utils'
import type { PriceRangeProps } from '../PriceRange'
import Component from '../PriceRange'
import mdx from './PriceRange.mdx'

const PriceRangeTemplate: Story<PriceRangeProps> = (props) => (
<Component {...props} />
)

export const PriceRange = PriceRangeTemplate.bind({})

function formatter(price: number) {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
}).format(price)
}

const argTypes: ComponentArgTypes<PriceRangeProps> = {
min: {
control: { type: 'number', min: 0 },
defaultValue: 0,
},
max: {
control: { type: 'number', min: 1 },
defaultValue: 500,
},
formatter: {
defaultValue: formatter,
},
}

export default {
title: 'Molecules/PriceRange',
argTypes,
parameters: {
docs: {
page: mdx,
},
},
} as Meta
7 changes: 4 additions & 3 deletions themes/theme-b2c-tailwind/src/molecules/index.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@import "./bullets.css";
@import "./search-input.css";
@import "./icon-button.css"
@import './bullets.css';
@import './search-input.css';
@import './icon-button.css';
@import './price-range.css';
3 changes: 3 additions & 0 deletions themes/theme-b2c-tailwind/src/molecules/price-range.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[data-store-price-range-values] {
@apply mt-4 flex justify-between;
}

0 comments on commit e5c5d9a

Please sign in to comment.