@toptal/picasso-utils 1.0.1-alpha-fx-4861-find-missing-deep-imports-in-staff-portal-ca4ef823d.4082 → 1.0.1-alpha-fx-4861-find-missing-deep-imports-in-staff-portal-25389459e.4083
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-package/tsconfig.tsbuildinfo +1 -0
- package/package.json +5 -9
- package/src/index.ts +1 -0
- package/src/utils/Breakpoints/story/Breakpoints.example.tsx +49 -0
- package/src/utils/Breakpoints/story/MediaQueries.example.tsx +18 -0
- package/src/utils/Breakpoints/story/index.jsx +60 -0
- package/src/utils/Breakpoints/story/useBreakpoint.example.tsx +17 -0
- package/src/utils/Breakpoints/story/useScreens.example.tsx +60 -0
- package/src/utils/Colors/index.ts +2 -0
- package/src/utils/Colors/story/Default.example.tsx +59 -0
- package/src/utils/Colors/story/HowToUse.example.tsx +14 -0
- package/src/utils/Colors/story/index.jsx +21 -0
- package/src/utils/Formatters/format-amount.ts +34 -0
- package/src/utils/Formatters/index.ts +3 -0
- package/src/utils/Formatters/story/amount.example.tsx +63 -0
- package/src/utils/Formatters/story/index.jsx +16 -0
- package/src/utils/Formatters/test.ts +102 -0
- package/src/utils/Gradients/index.ts +2 -0
- package/src/utils/Gradients/story/Default.example.tsx +30 -0
- package/src/utils/Gradients/story/HowToUse.example.tsx +26 -0
- package/src/utils/Gradients/story/index.jsx +26 -0
- package/src/utils/Modal/__snapshots__/test.tsx.snap +209 -0
- package/src/utils/Modal/index.ts +2 -0
- package/src/utils/Modal/modal-manager.ts +27 -0
- package/src/utils/Modal/test.tsx +86 -0
- package/src/utils/Modal/use-modal.tsx +17 -0
- package/src/utils/Shadows/story/Default.example.tsx +45 -0
- package/src/utils/Shadows/story/HowToUse.example.tsx +19 -0
- package/src/utils/Shadows/story/index.jsx +19 -0
- package/src/utils/Transitions/Rotate180/Rotate180.tsx +44 -0
- package/src/utils/Transitions/Rotate180/__snapshots__/test.tsx.snap +29 -0
- package/src/utils/Transitions/Rotate180/index.ts +4 -0
- package/src/utils/Transitions/Rotate180/story/Default.example.tsx +22 -0
- package/src/utils/Transitions/Rotate180/styles.ts +11 -0
- package/src/utils/Transitions/Rotate180/test.tsx +26 -0
- package/src/utils/Transitions/index.ts +2 -0
- package/src/utils/Transitions/story/index.jsx +13 -0
- package/src/utils/Utils/story/Browser.example.tsx +28 -0
- package/src/utils/Utils/story/Colors.example.tsx +29 -0
- package/src/utils/Utils/story/Generic.example.tsx +30 -0
- package/src/utils/Utils/story/React.example.tsx +32 -0
- package/src/utils/Utils/story/Strings.example.tsx +33 -0
- package/src/utils/__tests__/use-page-scroll-lock.test.tsx +117 -0
- package/src/utils/capitalize.ts +1 -0
- package/src/utils/constants.ts +1 -0
- package/src/utils/disable-unsupported-props.ts +45 -0
- package/src/utils/forward-ref.ts +38 -0
- package/src/utils/get-name-initials.ts +15 -0
- package/src/utils/get-react-node-text-content.ts +36 -0
- package/src/utils/index.ts +92 -0
- package/src/utils/is-boolean.ts +3 -0
- package/src/utils/is-number.ts +3 -0
- package/src/utils/is-overflown.ts +20 -0
- package/src/utils/is-pointer-device.ts +9 -0
- package/src/utils/is-string.ts +3 -0
- package/src/utils/is-substring.ts +4 -0
- package/src/utils/kebab-to-camel-case.ts +7 -0
- package/src/utils/loader-palette.ts +9 -0
- package/src/utils/monads.ts +1 -0
- package/src/utils/noop.ts +1 -0
- package/src/utils/sum.ts +4 -0
- package/src/utils/test.tsx +372 -0
- package/src/utils/to-title-case.ts +14 -0
- package/src/utils/unsafe-error-log.ts +5 -0
- package/src/utils/use-combined-refs.ts +26 -0
- package/src/utils/use-deprecation-warnings.ts +56 -0
- package/src/utils/use-multiple-forward-refs.ts +37 -0
- package/src/utils/use-page-scroll-lock.ts +64 -0
- package/src/utils/use-safe-state.ts +25 -0
- package/src/utils/use-width-of.ts +26 -0
- package/src/utils/useBoolean/index.ts +1 -0
- package/src/utils/useBoolean/test.tsx +25 -0
- package/src/utils/useBoolean/use-boolean.ts +30 -0
- package/src/utils/useInterval/index.ts +1 -0
- package/src/utils/useInterval/test.ts +61 -0
- package/src/utils/useInterval/use-interval.ts +46 -0
- package/src/utils/useMouseEnter/index.ts +1 -0
- package/src/utils/useMouseEnter/test.ts +51 -0
- package/src/utils/useMouseEnter/use-mouse-enter.ts +30 -0
- package/src/utils/useOnScreen/index.ts +1 -0
- package/src/utils/useOnScreen/use-on-screen.ts +50 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import PicassoBook from '~/.storybook/components/PicassoBook'
|
|
2
|
+
|
|
3
|
+
const page = PicassoBook.section('Utils').createPage(
|
|
4
|
+
'Breakpoints',
|
|
5
|
+
`
|
|
6
|
+
For optimal user experience, we need to be able to adapt layout
|
|
7
|
+
at various breakpoints. Each breakpoint matches with a fixed screen
|
|
8
|
+
width.
|
|
9
|
+
`
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
page
|
|
13
|
+
.createChapter()
|
|
14
|
+
.addExample(
|
|
15
|
+
'utils/Breakpoints/story/Breakpoints.example.tsx',
|
|
16
|
+
{
|
|
17
|
+
title: 'Breakpoints',
|
|
18
|
+
description: `
|
|
19
|
+
The list of breakpoint names and pixel-values we use while we design and do layouts
|
|
20
|
+
`,
|
|
21
|
+
showEditCode: false,
|
|
22
|
+
takeScreenshot: false,
|
|
23
|
+
},
|
|
24
|
+
'base/Utils'
|
|
25
|
+
)
|
|
26
|
+
.addExample(
|
|
27
|
+
'utils/Breakpoints/story/MediaQueries.example.tsx',
|
|
28
|
+
{
|
|
29
|
+
title: 'Media queries',
|
|
30
|
+
description: `
|
|
31
|
+
Picasso provides a function 'screens' to be able to
|
|
32
|
+
easily create media queries based on the given breakpoints
|
|
33
|
+
`,
|
|
34
|
+
takeScreenshot: false,
|
|
35
|
+
},
|
|
36
|
+
'base/Utils'
|
|
37
|
+
)
|
|
38
|
+
.addExample(
|
|
39
|
+
'utils/Breakpoints/story/useBreakpoint.example.tsx',
|
|
40
|
+
{
|
|
41
|
+
title: 'useBreakpoint',
|
|
42
|
+
description: `
|
|
43
|
+
Provides programmatic way to check what screen size defined by breakpoints is active
|
|
44
|
+
`,
|
|
45
|
+
takeScreenshot: false,
|
|
46
|
+
},
|
|
47
|
+
'base/Utils'
|
|
48
|
+
)
|
|
49
|
+
.addExample(
|
|
50
|
+
'utils/Breakpoints/story/useScreens.example.tsx',
|
|
51
|
+
{
|
|
52
|
+
title: 'useScreens',
|
|
53
|
+
description: `
|
|
54
|
+
Provides a programmatic way to switch between different values depending on screen size. The function returned by useScreens is memoized per screen size, so there are no performance penalties if re-rendering happens often.
|
|
55
|
+
`,
|
|
56
|
+
showEditCode: true,
|
|
57
|
+
takeScreenshot: false,
|
|
58
|
+
},
|
|
59
|
+
'base/Utils'
|
|
60
|
+
)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useBreakpoint } from '@toptal/picasso-utils'
|
|
3
|
+
import { Typography } from '@toptal/picasso'
|
|
4
|
+
|
|
5
|
+
const Example = () => {
|
|
6
|
+
const isSmall = useBreakpoint('sm')
|
|
7
|
+
const isSmallOrMedium = useBreakpoint(['sm', 'md'])
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
<Typography>{`Breakpoint 'small' matches: ${isSmall}`}</Typography>
|
|
12
|
+
<Typography>{`Breakpoint 'small' or 'medium' matches: ${isSmallOrMedium}`}</Typography>
|
|
13
|
+
</>
|
|
14
|
+
)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default Example
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useScreens, SPACING_8 } from '@toptal/picasso-utils'
|
|
3
|
+
import type { ButtonVariantType } from '@toptal/picasso'
|
|
4
|
+
import { Typography, Button, Container } from '@toptal/picasso'
|
|
5
|
+
|
|
6
|
+
const Example = () => {
|
|
7
|
+
const screens = useScreens<ButtonVariantType>()
|
|
8
|
+
const screenTexts = useScreens<string>()
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<>
|
|
12
|
+
<Container bottom={SPACING_8}>
|
|
13
|
+
<Typography variant='heading' size='medium'>
|
|
14
|
+
Current screen breakpoint:{' '}
|
|
15
|
+
{screenTexts({
|
|
16
|
+
xs: 'xs',
|
|
17
|
+
sm: 'sm',
|
|
18
|
+
md: 'md',
|
|
19
|
+
lg: 'lg',
|
|
20
|
+
xl: 'xl',
|
|
21
|
+
})}
|
|
22
|
+
</Typography>
|
|
23
|
+
</Container>
|
|
24
|
+
<Typography as='span'>
|
|
25
|
+
The button below will use:
|
|
26
|
+
<ul>
|
|
27
|
+
<li>
|
|
28
|
+
<strong>secondary</strong> variant on small screens
|
|
29
|
+
</li>
|
|
30
|
+
<li>
|
|
31
|
+
<strong>positive</strong> variant on large screens
|
|
32
|
+
</li>
|
|
33
|
+
<li>
|
|
34
|
+
<strong>primary</strong> for all other screens (the default value)
|
|
35
|
+
</li>
|
|
36
|
+
</ul>
|
|
37
|
+
</Typography>
|
|
38
|
+
|
|
39
|
+
<Button
|
|
40
|
+
variant={screens(
|
|
41
|
+
{
|
|
42
|
+
sm: 'secondary',
|
|
43
|
+
lg: 'positive',
|
|
44
|
+
},
|
|
45
|
+
'primary'
|
|
46
|
+
)}
|
|
47
|
+
>
|
|
48
|
+
{screenTexts(
|
|
49
|
+
{
|
|
50
|
+
sm: 'small (secondary)',
|
|
51
|
+
lg: 'large (positive)',
|
|
52
|
+
},
|
|
53
|
+
'default (primary)'
|
|
54
|
+
)}
|
|
55
|
+
</Button>
|
|
56
|
+
</>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default Example
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React, { Fragment } from 'react'
|
|
2
|
+
import { palette, SPACING_8, SPACING_4 } from '@toptal/picasso-utils'
|
|
3
|
+
import { Grid, Paper, Typography, Container } from '@toptal/picasso'
|
|
4
|
+
|
|
5
|
+
const colorGroups = Object.entries(palette)
|
|
6
|
+
|
|
7
|
+
const Example = () => (
|
|
8
|
+
<>
|
|
9
|
+
{colorGroups.map(([colorGroupName, colorGroup]) => (
|
|
10
|
+
<Fragment key={colorGroupName}>
|
|
11
|
+
<Container top={SPACING_8} bottom={SPACING_4}>
|
|
12
|
+
<Typography variant='heading' size='large'>
|
|
13
|
+
{colorGroupName}
|
|
14
|
+
</Typography>
|
|
15
|
+
</Container>
|
|
16
|
+
<ColorGroup
|
|
17
|
+
colors={Object.entries(colorGroup)}
|
|
18
|
+
colorGroupName={colorGroupName}
|
|
19
|
+
/>
|
|
20
|
+
</Fragment>
|
|
21
|
+
))}
|
|
22
|
+
</>
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
const ColorGroup = ({
|
|
26
|
+
colors,
|
|
27
|
+
colorGroupName,
|
|
28
|
+
}: {
|
|
29
|
+
colors: [string, string][]
|
|
30
|
+
colorGroupName: string
|
|
31
|
+
}) => (
|
|
32
|
+
<Grid spacing={16}>
|
|
33
|
+
{colors.map(([colorName, color]) => (
|
|
34
|
+
<Grid.Item key={colorName}>
|
|
35
|
+
<Paper style={{ padding: '1rem' }}>
|
|
36
|
+
<ColorRectangle color={color} />
|
|
37
|
+
<Typography size='xsmall'>
|
|
38
|
+
{`${colorGroupName}.${colorName}`}
|
|
39
|
+
</Typography>
|
|
40
|
+
<Typography variant='heading' size='small'>
|
|
41
|
+
{color.toUpperCase()}
|
|
42
|
+
</Typography>
|
|
43
|
+
</Paper>
|
|
44
|
+
</Grid.Item>
|
|
45
|
+
))}
|
|
46
|
+
</Grid>
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
const ColorRectangle = ({ color }: { color: string }) => (
|
|
50
|
+
<div
|
|
51
|
+
style={{
|
|
52
|
+
width: '7rem',
|
|
53
|
+
height: '7rem',
|
|
54
|
+
backgroundColor: color,
|
|
55
|
+
}}
|
|
56
|
+
/>
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
export default Example
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { palette } from '@toptal/picasso-utils'
|
|
3
|
+
import { Typography } from '@toptal/picasso'
|
|
4
|
+
|
|
5
|
+
const Example = () => (
|
|
6
|
+
<Typography>
|
|
7
|
+
Use the color just directly from Picasso. For example,{' '}
|
|
8
|
+
<span style={{ color: palette.blue.main }}>
|
|
9
|
+
I am painted by the blue main color
|
|
10
|
+
</span>
|
|
11
|
+
</Typography>
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
export default Example
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import PicassoBook from '~/.storybook/components/PicassoBook'
|
|
2
|
+
|
|
3
|
+
const page = PicassoBook.section('Utils').createPage(
|
|
4
|
+
'Colors',
|
|
5
|
+
`
|
|
6
|
+
The Toptal color palette comprises the core brand colors
|
|
7
|
+
plus a range of shades and tints.
|
|
8
|
+
`
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
page
|
|
12
|
+
.createChapter()
|
|
13
|
+
.addExample(
|
|
14
|
+
'utils/Colors/story/HowToUse.example.tsx',
|
|
15
|
+
{
|
|
16
|
+
title: 'How to use',
|
|
17
|
+
takeScreenshot: false,
|
|
18
|
+
},
|
|
19
|
+
'base/Utils'
|
|
20
|
+
)
|
|
21
|
+
.addExample('utils/Colors/story/Default.example.tsx', 'Colors', 'base/Utils')
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const DEFAULT_CURRENCY = 'USD'
|
|
2
|
+
export const DEFAULT_LOCALE = 'en-US'
|
|
3
|
+
|
|
4
|
+
export interface FormatAmount {
|
|
5
|
+
/** The amount to be formatted */
|
|
6
|
+
amount: number | string
|
|
7
|
+
/** Currency which need to be applied on the amount (ISO format) https://www.currency-iso.org/en/home/tables/table-a1.html */
|
|
8
|
+
currency?: string
|
|
9
|
+
/** Locale identifiers are case-insensitive ASCII. However, it's conventional to use title case (first letter capitalized, successive letters lower case) for script code, upper case for region codes, and lower case for everything else. */
|
|
10
|
+
locale?: string
|
|
11
|
+
options?: {
|
|
12
|
+
/** The minimum number of fraction digits to display **/
|
|
13
|
+
minimumFractionDigits?: number
|
|
14
|
+
|
|
15
|
+
/** The maximum number of fraction digits to display **/
|
|
16
|
+
maximumFractionDigits?: number
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const formatAmount = ({
|
|
21
|
+
amount,
|
|
22
|
+
currency = DEFAULT_CURRENCY,
|
|
23
|
+
locale = DEFAULT_LOCALE,
|
|
24
|
+
options,
|
|
25
|
+
}: FormatAmount) => {
|
|
26
|
+
const transformedAmount = typeof amount === 'string' ? Number(amount) : amount
|
|
27
|
+
|
|
28
|
+
return Intl.NumberFormat(locale, {
|
|
29
|
+
style: 'currency',
|
|
30
|
+
minimumFractionDigits: options?.minimumFractionDigits,
|
|
31
|
+
maximumFractionDigits: options?.maximumFractionDigits,
|
|
32
|
+
currency,
|
|
33
|
+
}).format(transformedAmount)
|
|
34
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Container, Typography } from '@toptal/picasso'
|
|
2
|
+
import { SPACING_4, formatAmount } from '@toptal/picasso-utils'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
|
|
5
|
+
const exampleAmount1 = 1575
|
|
6
|
+
const exampleAmount2 = '890'
|
|
7
|
+
|
|
8
|
+
const Example = () => (
|
|
9
|
+
<div>
|
|
10
|
+
<Container bottom={SPACING_4}>
|
|
11
|
+
<Typography>
|
|
12
|
+
This component exposes a currency formatting utility, which converts
|
|
13
|
+
numbers, into string decorated with currency symbols/codes in the
|
|
14
|
+
required locale format.
|
|
15
|
+
</Typography>
|
|
16
|
+
</Container>
|
|
17
|
+
<Container bottom={SPACING_4}>
|
|
18
|
+
<Typography variant='heading' size='medium'>
|
|
19
|
+
Without using Amount format helper
|
|
20
|
+
</Typography>
|
|
21
|
+
<Typography>
|
|
22
|
+
This is an example pure string usage of the amount ${exampleAmount1} and{' '}
|
|
23
|
+
€{exampleAmount2}.
|
|
24
|
+
</Typography>
|
|
25
|
+
</Container>
|
|
26
|
+
<Container bottom={SPACING_4}>
|
|
27
|
+
<Typography variant='heading' size='medium'>
|
|
28
|
+
Using Amount format helper
|
|
29
|
+
</Typography>
|
|
30
|
+
<Typography>
|
|
31
|
+
This is an example pure string usage of the amount{' '}
|
|
32
|
+
{formatAmount({ amount: exampleAmount1 })} and{' '}
|
|
33
|
+
{formatAmount({ amount: exampleAmount2, currency: 'EUR' })}.
|
|
34
|
+
</Typography>
|
|
35
|
+
</Container>
|
|
36
|
+
<Container bottom={SPACING_4}>
|
|
37
|
+
<Typography variant='heading' size='medium'>
|
|
38
|
+
Using fraction digits options:
|
|
39
|
+
</Typography>
|
|
40
|
+
<Typography>
|
|
41
|
+
minimumFractionDigits: 3 with value: {exampleAmount1}
|
|
42
|
+
</Typography>
|
|
43
|
+
<Typography>
|
|
44
|
+
output:{' '}
|
|
45
|
+
{formatAmount({
|
|
46
|
+
amount: exampleAmount1,
|
|
47
|
+
options: { minimumFractionDigits: 3 },
|
|
48
|
+
})}
|
|
49
|
+
</Typography>
|
|
50
|
+
<Typography>minimumFractionDigits: 1 with value: 1575.1234</Typography>
|
|
51
|
+
<Typography>
|
|
52
|
+
output:{' '}
|
|
53
|
+
{formatAmount({
|
|
54
|
+
amount: 890.1234,
|
|
55
|
+
options: { maximumFractionDigits: 1 },
|
|
56
|
+
currency: 'EUR',
|
|
57
|
+
})}
|
|
58
|
+
</Typography>
|
|
59
|
+
</Container>
|
|
60
|
+
</div>
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
export default Example
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import PicassoBook from '~/.storybook/components/PicassoBook'
|
|
2
|
+
|
|
3
|
+
const page = PicassoBook.section('Utils').createPage(
|
|
4
|
+
'Formatters',
|
|
5
|
+
`
|
|
6
|
+
For consistent user experience, we need to standardize formatters.
|
|
7
|
+
`
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
page
|
|
11
|
+
.createChapter()
|
|
12
|
+
.addExample(
|
|
13
|
+
'utils/Formatters/story/amount.example.tsx',
|
|
14
|
+
'Amount Formatter',
|
|
15
|
+
'base/Utils'
|
|
16
|
+
)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { formatAmount } from './format-amount'
|
|
2
|
+
|
|
3
|
+
describe('formatAmount', () => {
|
|
4
|
+
describe('when `locale` is defined', () => {
|
|
5
|
+
it('formats `en-US` locale by default', () => {
|
|
6
|
+
expect(formatAmount({ amount: 1500 })).toBe('$1,500.00')
|
|
7
|
+
})
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
describe('when `locale` is `fr-FR`', () => {
|
|
11
|
+
it('formats `fr-FR` locale', () => {
|
|
12
|
+
expect(formatAmount({ amount: 1500, locale: 'fr-FR' })).toBe(
|
|
13
|
+
'1 500,00 $US'
|
|
14
|
+
)
|
|
15
|
+
})
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
describe('when `EUR` currency provided', () => {
|
|
19
|
+
it('formats EUR currency', () => {
|
|
20
|
+
expect(formatAmount({ amount: 1750, currency: 'EUR' })).toBe('€1,750.00')
|
|
21
|
+
})
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
describe('when no currency provided', () => {
|
|
25
|
+
it('formats USD currency by default', () => {
|
|
26
|
+
expect(formatAmount({ amount: 1500 })).toBe('$1,500.00')
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
describe('when `amount` has 4 digits of decimals', () => {
|
|
31
|
+
it('formats two digit of decimals USD amount', () => {
|
|
32
|
+
expect(formatAmount({ amount: 24.2587 })).toBe('$24.26')
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
describe('when `amount` is negative', () => {
|
|
37
|
+
it('formats negative USD amount', () => {
|
|
38
|
+
expect(formatAmount({ amount: -14.25 })).toBe('-$14.25')
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
describe('when `amount` is zero', () => {
|
|
43
|
+
it('formats zero USD amount', () => {
|
|
44
|
+
expect(formatAmount({ amount: 0 })).toBe('$0.00')
|
|
45
|
+
})
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
describe('when `amount` is string', () => {
|
|
49
|
+
it('formats amount as a number', () => {
|
|
50
|
+
expect(formatAmount({ amount: '15' })).toBe('$15.00')
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
describe('options', () => {
|
|
55
|
+
it('displays decimals when options are not provided', () => {
|
|
56
|
+
expect(formatAmount({ amount: '15' })).toBe('$15.00')
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('does not display decimals when options are 0', () => {
|
|
60
|
+
expect(
|
|
61
|
+
formatAmount({
|
|
62
|
+
amount: '15',
|
|
63
|
+
options: {
|
|
64
|
+
minimumFractionDigits: 0,
|
|
65
|
+
maximumFractionDigits: 0,
|
|
66
|
+
},
|
|
67
|
+
})
|
|
68
|
+
).toBe('$15')
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('displays min number of decimal digits', () => {
|
|
72
|
+
expect(
|
|
73
|
+
formatAmount({
|
|
74
|
+
amount: '15',
|
|
75
|
+
options: {
|
|
76
|
+
minimumFractionDigits: 3,
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
).toBe('$15.000')
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('displays max number of decimal digits', () => {
|
|
83
|
+
expect(
|
|
84
|
+
formatAmount({
|
|
85
|
+
amount: '15.1234',
|
|
86
|
+
options: {
|
|
87
|
+
maximumFractionDigits: 2,
|
|
88
|
+
},
|
|
89
|
+
})
|
|
90
|
+
).toBe('$15.12')
|
|
91
|
+
|
|
92
|
+
expect(
|
|
93
|
+
formatAmount({
|
|
94
|
+
amount: '15.1294',
|
|
95
|
+
options: {
|
|
96
|
+
maximumFractionDigits: 2,
|
|
97
|
+
},
|
|
98
|
+
})
|
|
99
|
+
).toBe('$15.13')
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
})
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { gradients, shadows } from '@toptal/picasso-utils'
|
|
3
|
+
import { Typography, Grid, Container } from '@toptal/picasso'
|
|
4
|
+
|
|
5
|
+
const Example = () => (
|
|
6
|
+
<Grid>
|
|
7
|
+
{Object.entries(gradients).map(([gradientKey, gradientValue]) => (
|
|
8
|
+
<Grid.Item sm={6} key={gradientKey}>
|
|
9
|
+
<Container>
|
|
10
|
+
<Typography size='large'>{gradientKey}</Typography>
|
|
11
|
+
</Container>
|
|
12
|
+
<Container>
|
|
13
|
+
<GradientRectangle gradient={gradientValue} />
|
|
14
|
+
</Container>
|
|
15
|
+
</Grid.Item>
|
|
16
|
+
))}
|
|
17
|
+
</Grid>
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
const GradientRectangle = ({ gradient }: { gradient: string }) => (
|
|
21
|
+
<div
|
|
22
|
+
style={{
|
|
23
|
+
height: '14rem',
|
|
24
|
+
background: gradient,
|
|
25
|
+
boxShadow: shadows[5],
|
|
26
|
+
}}
|
|
27
|
+
/>
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
export default Example
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { gradients, SPACING_4 } from '@toptal/picasso-utils'
|
|
3
|
+
import { Typography, Container } from '@toptal/picasso'
|
|
4
|
+
|
|
5
|
+
const Example = () => (
|
|
6
|
+
<>
|
|
7
|
+
<Container bottom={SPACING_4}>
|
|
8
|
+
<Typography>
|
|
9
|
+
Use the gradient just directly from Picasso and apply it to any element
|
|
10
|
+
as{' '}
|
|
11
|
+
<Typography inline underline='solid'>
|
|
12
|
+
background
|
|
13
|
+
</Typography>{' '}
|
|
14
|
+
style property.
|
|
15
|
+
</Typography>
|
|
16
|
+
</Container>
|
|
17
|
+
<div
|
|
18
|
+
style={{
|
|
19
|
+
height: '5rem',
|
|
20
|
+
background: gradients.blue,
|
|
21
|
+
}}
|
|
22
|
+
/>
|
|
23
|
+
</>
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
export default Example
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import PicassoBook from '~/.storybook/components/PicassoBook'
|
|
2
|
+
|
|
3
|
+
const page = PicassoBook.section('Utils').createPage(
|
|
4
|
+
'Gradients',
|
|
5
|
+
`Gradients are important visual elements. They are versatile and can be combined with other elements. To keep our visual language consistent it's important to make a correct use of our gradients.
|
|
6
|
+
|
|
7
|
+
These are the recommended gradients.
|
|
8
|
+
|
|
9
|
+
Our gradients are made using our brand colors, always keeping a 200 points interval. For example: Blue 500 to Blue 700.`
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
page
|
|
13
|
+
.createChapter()
|
|
14
|
+
.addExample(
|
|
15
|
+
'utils/Gradients/story/HowToUse.example.tsx',
|
|
16
|
+
{
|
|
17
|
+
title: 'How to use',
|
|
18
|
+
takeScreenshot: false,
|
|
19
|
+
},
|
|
20
|
+
'base/Utils'
|
|
21
|
+
)
|
|
22
|
+
.addExample(
|
|
23
|
+
'utils/Gradients/story/Default.example.tsx',
|
|
24
|
+
'Gradients',
|
|
25
|
+
'base/Utils'
|
|
26
|
+
)
|