@automattic/vip-design-system 0.19.1 → 0.20.0
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/README.md +12 -0
- package/build/system/Button/Button.js +5 -0
- package/build/system/Button/Button.stories.js +8 -0
- package/build/system/Heading/Heading.js +7 -3
- package/build/system/Heading/Heading.stories.js +0 -3
- package/build/system/Link/Link.js +2 -1
- package/build/system/NewForm/FormSelect.test.js +79 -7
- package/build/system/Progress/Progress.js +45 -16
- package/build/system/Progress/Progress.stories.js +21 -4
- package/build/system/Table/Table.js +7 -3
- package/build/system/Wizard/Wizard.js +1 -3
- package/build/system/Wizard/Wizard.stories.js +18 -8
- package/build/system/Wizard/WizardStep.js +19 -12
- package/build/system/Wizard/WizardStepHorizontal.js +18 -8
- package/build/system/index.js +0 -5
- package/package.json +2 -1
- package/src/system/Button/Button.js +5 -0
- package/src/system/Button/Button.stories.jsx +3 -0
- package/src/system/Heading/Heading.js +18 -12
- package/src/system/Heading/Heading.stories.jsx +0 -1
- package/src/system/Link/Link.js +1 -0
- package/src/system/NewForm/FormSelect.test.js +38 -0
- package/src/system/Progress/Progress.js +55 -26
- package/src/system/Progress/Progress.stories.jsx +15 -8
- package/src/system/Table/Table.js +6 -2
- package/src/system/Wizard/Wizard.js +1 -2
- package/src/system/Wizard/Wizard.stories.jsx +6 -6
- package/src/system/Wizard/WizardStep.js +23 -25
- package/src/system/Wizard/WizardStepHorizontal.js +13 -7
- package/src/system/index.js +0 -3
- package/src/system/ResourceList/ResourceItem.js +0 -66
- package/src/system/ResourceList/ResourceList.js +0 -108
- package/src/system/ResourceList/ResourceList.stories.jsx +0 -306
- package/src/system/ResourceList/index.js +0 -7
|
@@ -3,24 +3,30 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* External dependencies
|
|
5
5
|
*/
|
|
6
|
+
import React from 'react';
|
|
6
7
|
import { Heading as ThemeHeading } from 'theme-ui';
|
|
7
8
|
import PropTypes from 'prop-types';
|
|
8
9
|
import classNames from 'classnames';
|
|
9
10
|
|
|
10
|
-
const Heading = (
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
const Heading = React.forwardRef(
|
|
12
|
+
( { variant = 'h3', sx, className = null, ...props }, forwardRef ) => (
|
|
13
|
+
<ThemeHeading
|
|
14
|
+
as={ variant }
|
|
15
|
+
sx={ {
|
|
16
|
+
color: 'heading',
|
|
17
|
+
// pass variant prop to sx
|
|
18
|
+
variant: `text.${ variant }`,
|
|
19
|
+
...sx,
|
|
20
|
+
} }
|
|
21
|
+
className={ classNames( 'vip-heading-component', className ) }
|
|
22
|
+
ref={ forwardRef }
|
|
23
|
+
{ ...props }
|
|
24
|
+
/>
|
|
25
|
+
)
|
|
22
26
|
);
|
|
23
27
|
|
|
28
|
+
Heading.displayName = 'Heading';
|
|
29
|
+
|
|
24
30
|
Heading.propTypes = {
|
|
25
31
|
variant: PropTypes.string,
|
|
26
32
|
sx: PropTypes.object,
|
package/src/system/Link/Link.js
CHANGED
|
@@ -21,10 +21,48 @@ const defaultProps = {
|
|
|
21
21
|
options,
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
+
const groupedProps = {
|
|
25
|
+
...defaultProps,
|
|
26
|
+
options: [
|
|
27
|
+
{
|
|
28
|
+
label: 'Group name',
|
|
29
|
+
options: [ options[ 0 ] ],
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
label: 'Another Group name',
|
|
33
|
+
options: [ options[ 1 ], options[ 2 ] ],
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
|
|
24
38
|
describe( '<FormSelect />', () => {
|
|
25
39
|
it( 'renders the FormSelect component', async () => {
|
|
26
40
|
const { container } = render( <FormSelect id="my_desert_list" { ...defaultProps } /> );
|
|
27
41
|
|
|
42
|
+
expect( screen.getByLabelText( defaultProps.label ) ).toBeInTheDocument();
|
|
43
|
+
expect( screen.getByRole( 'combobox' ) ).toBeInTheDocument();
|
|
44
|
+
expect( screen.getAllByRole( 'option' ) ).toHaveLength( 3 );
|
|
45
|
+
expect( screen.queryByRole( 'group' ) ).not.toBeInTheDocument();
|
|
46
|
+
|
|
47
|
+
// Check for accessibility issues
|
|
48
|
+
await expect( await axe( container ) ).toHaveNoViolations();
|
|
49
|
+
} );
|
|
50
|
+
|
|
51
|
+
it( 'renders the FormSelect component with optgroup when options are grouped', async () => {
|
|
52
|
+
const { container } = render( <FormSelect id="my_desert_list" { ...groupedProps } /> );
|
|
53
|
+
|
|
54
|
+
expect( screen.getByLabelText( defaultProps.label ) ).toBeInTheDocument();
|
|
55
|
+
expect( screen.getByRole( 'combobox' ) ).toBeInTheDocument();
|
|
56
|
+
expect( screen.getAllByRole( 'option' ) ).toHaveLength( 3 );
|
|
57
|
+
expect( screen.getAllByRole( 'group' ) ).toHaveLength( 2 );
|
|
58
|
+
|
|
59
|
+
// Check for accessibility issues
|
|
60
|
+
await expect( await axe( container ) ).toHaveNoViolations();
|
|
61
|
+
} );
|
|
62
|
+
|
|
63
|
+
it( 'renders the FormSelect component when isInline is true', async () => {
|
|
64
|
+
const { container } = render( <FormSelect id="my_desert_list" isInline { ...defaultProps } /> );
|
|
65
|
+
|
|
28
66
|
expect( screen.getByLabelText( defaultProps.label ) ).toBeInTheDocument();
|
|
29
67
|
expect( screen.getByRole( 'combobox' ) ).toBeInTheDocument();
|
|
30
68
|
|
|
@@ -3,45 +3,74 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* External dependencies
|
|
5
5
|
*/
|
|
6
|
+
import React from 'react';
|
|
6
7
|
import { Progress as ThemeProgress } from 'theme-ui';
|
|
7
8
|
import PropTypes from 'prop-types';
|
|
9
|
+
import classNames from 'classnames';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Internal dependencies
|
|
11
13
|
*/
|
|
12
14
|
import { Spinner } from '../Spinner';
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
15
|
+
import { MdCheck } from 'react-icons/md';
|
|
16
|
+
import { Box, Text, Flex } from '../';
|
|
17
|
+
|
|
18
|
+
const prefix = 'vip-progress-component';
|
|
19
|
+
const uniqueID = () => Math.random().toString( 36 ).substring( 7 );
|
|
20
|
+
|
|
21
|
+
const Progress = React.forwardRef(
|
|
22
|
+
( { steps, activeStep, sx, forLabel = '', className, ...props }, forwardRef ) => {
|
|
23
|
+
const stepsTotal = steps.length;
|
|
24
|
+
const isDone = activeStep === stepsTotal - 1;
|
|
25
|
+
const instance = uniqueID();
|
|
26
|
+
const htmlFor = `${ prefix }-${ instance }`;
|
|
27
|
+
const currentValue = activeStep + 1;
|
|
15
28
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
<
|
|
34
|
-
{
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
return (
|
|
30
|
+
<Box className={ classNames( prefix, className ) }>
|
|
31
|
+
<ThemeProgress
|
|
32
|
+
sx={ {
|
|
33
|
+
color: 'primary',
|
|
34
|
+
backgroundColor: 'background',
|
|
35
|
+
...sx,
|
|
36
|
+
} }
|
|
37
|
+
max={ stepsTotal }
|
|
38
|
+
value={ currentValue }
|
|
39
|
+
id={ htmlFor }
|
|
40
|
+
aria-label={ forLabel }
|
|
41
|
+
ref={ forwardRef }
|
|
42
|
+
{ ...props }
|
|
43
|
+
/>
|
|
44
|
+
|
|
45
|
+
{ steps && (
|
|
46
|
+
<Flex
|
|
47
|
+
sx={ { alignItems: 'center', mt: 2 } }
|
|
48
|
+
aria-live="polite"
|
|
49
|
+
aria-atomic="true"
|
|
50
|
+
aria-describedby={ htmlFor }
|
|
51
|
+
>
|
|
52
|
+
{ ! isDone && <Spinner size={ 24 } aria-hidden="true" /> }
|
|
53
|
+
{ isDone && <MdCheck size={ 24 } aria-hidden="true" /> }
|
|
54
|
+
|
|
55
|
+
<Text sx={ { ml: 2, mb: 0 } }>
|
|
56
|
+
<strong>{ `${ currentValue } of ${ stepsTotal }` }: </strong>
|
|
57
|
+
<Text as="span" sx={ { color: 'muted' } }>
|
|
58
|
+
{ steps[ activeStep ] }
|
|
59
|
+
</Text>
|
|
60
|
+
</Text>
|
|
61
|
+
</Flex>
|
|
62
|
+
) }
|
|
63
|
+
</Box>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
40
66
|
);
|
|
41
67
|
|
|
68
|
+
Progress.displayName = 'Progress';
|
|
69
|
+
|
|
42
70
|
Progress.propTypes = {
|
|
43
71
|
steps: PropTypes.array,
|
|
44
72
|
activeStep: PropTypes.number,
|
|
73
|
+
forLabel: PropTypes.node,
|
|
45
74
|
sx: PropTypes.object,
|
|
46
75
|
className: PropTypes.any,
|
|
47
76
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Internal dependencies
|
|
3
3
|
*/
|
|
4
|
+
import React, { useEffect } from 'react';
|
|
4
5
|
import { Progress } from '..';
|
|
5
6
|
|
|
6
7
|
export default {
|
|
@@ -8,11 +9,17 @@ export default {
|
|
|
8
9
|
component: Progress,
|
|
9
10
|
};
|
|
10
11
|
|
|
11
|
-
export const Default = () =>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
);
|
|
12
|
+
export const Default = () => {
|
|
13
|
+
const [ counter, setCounter ] = React.useState( 0 );
|
|
14
|
+
const steps = [ 'Downloading Data', 'Importing Data...', 'Finalizing', 'Done' ];
|
|
15
|
+
|
|
16
|
+
useEffect( () => {
|
|
17
|
+
setTimeout( () => {
|
|
18
|
+
if ( counter < steps.length - 1 ) {
|
|
19
|
+
setCounter( counter + 1 );
|
|
20
|
+
}
|
|
21
|
+
}, 2000 );
|
|
22
|
+
}, [ counter, setCounter ] );
|
|
23
|
+
|
|
24
|
+
return <Progress forLabel="Update site progress" steps={ steps } activeStep={ counter } />;
|
|
25
|
+
};
|
|
@@ -3,18 +3,22 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* External dependencies
|
|
5
5
|
*/
|
|
6
|
+
import React from 'react';
|
|
6
7
|
import PropTypes from 'prop-types';
|
|
7
8
|
import classNames from 'classnames';
|
|
8
9
|
|
|
9
|
-
const Table = ( { sx, className, ...props } ) => (
|
|
10
|
+
const Table = React.forwardRef( ( { sx, className, ...props }, forwardRef ) => (
|
|
10
11
|
<table
|
|
11
12
|
sx={ { width: '100%', minWidth: 1024, ...sx } }
|
|
12
13
|
cellPadding={ 0 }
|
|
13
14
|
cellSpacing={ 0 }
|
|
14
15
|
className={ classNames( 'vip-table-component', className ) }
|
|
16
|
+
ref={ forwardRef }
|
|
15
17
|
{ ...props }
|
|
16
18
|
/>
|
|
17
|
-
);
|
|
19
|
+
) );
|
|
20
|
+
|
|
21
|
+
Table.displayName = 'Table';
|
|
18
22
|
|
|
19
23
|
Table.propTypes = {
|
|
20
24
|
sx: PropTypes.object,
|
|
@@ -42,7 +42,7 @@ const Wizard = ( { steps, activeStep, variant, completed = [], className = null,
|
|
|
42
42
|
{ steps[ activeStep ].children }
|
|
43
43
|
</Box>
|
|
44
44
|
) : (
|
|
45
|
-
steps.map( ( { title, subTitle, children
|
|
45
|
+
steps.map( ( { title, subTitle, children }, index ) => (
|
|
46
46
|
<WizardStep
|
|
47
47
|
active={ index === activeStep }
|
|
48
48
|
complete={ completed.includes( index ) }
|
|
@@ -50,7 +50,6 @@ const Wizard = ( { steps, activeStep, variant, completed = [], className = null,
|
|
|
50
50
|
order={ index + 1 }
|
|
51
51
|
subTitle={ subTitle }
|
|
52
52
|
title={ title }
|
|
53
|
-
titleVariant={ titleVariant }
|
|
54
53
|
>
|
|
55
54
|
{ children }
|
|
56
55
|
</WizardStep>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** @jsxImportSource theme-ui */
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* External dependencies
|
|
3
5
|
*/
|
|
@@ -52,16 +54,14 @@ export const Default = () => {
|
|
|
52
54
|
);
|
|
53
55
|
};
|
|
54
56
|
|
|
55
|
-
export const
|
|
57
|
+
export const CustomTitle = () => {
|
|
56
58
|
const steps = [
|
|
57
59
|
{
|
|
58
|
-
title:
|
|
59
|
-
|
|
60
|
-
subTitle: <h2>You can bring a domain name you already own, or buy a new one.</h2>,
|
|
60
|
+
title: <h3 sx={ { m: 0 } }>Choose Domain</h3>,
|
|
61
|
+
subTitle: <span>You can bring a domain name you already own, or buy a new one.</span>,
|
|
61
62
|
},
|
|
62
63
|
{
|
|
63
|
-
title:
|
|
64
|
-
titleVariant: 'h1',
|
|
64
|
+
title: <h3 sx={ { m: 0 } }>Configure DNS</h3>,
|
|
65
65
|
},
|
|
66
66
|
];
|
|
67
67
|
return (
|
|
@@ -9,18 +9,10 @@ import PropTypes from 'prop-types';
|
|
|
9
9
|
/**
|
|
10
10
|
* Internal dependencies
|
|
11
11
|
*/
|
|
12
|
-
import { Card, Heading, Text } from '..';
|
|
12
|
+
import { Card, Heading, Text, Flex } from '..';
|
|
13
13
|
|
|
14
|
-
const WizardStep = ( {
|
|
15
|
-
|
|
16
|
-
subTitle,
|
|
17
|
-
complete = false,
|
|
18
|
-
children,
|
|
19
|
-
active,
|
|
20
|
-
order,
|
|
21
|
-
titleVariant = 'h4',
|
|
22
|
-
} ) => {
|
|
23
|
-
let borderLeftColor = 'borders.2';
|
|
14
|
+
const WizardStep = ( { title, subTitle, complete = false, children, active, order } ) => {
|
|
15
|
+
let borderLeftColor = 'border';
|
|
24
16
|
|
|
25
17
|
if ( complete ) {
|
|
26
18
|
borderLeftColor = 'success';
|
|
@@ -56,19 +48,26 @@ const WizardStep = ( {
|
|
|
56
48
|
data-step={ order }
|
|
57
49
|
data-active={ active || undefined }
|
|
58
50
|
>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
51
|
+
{ typeof title === 'string' ? (
|
|
52
|
+
<Heading
|
|
53
|
+
variant="h4"
|
|
54
|
+
sx={ {
|
|
55
|
+
mb: 0,
|
|
56
|
+
display: 'flex',
|
|
57
|
+
alignItems: 'center',
|
|
58
|
+
color: color,
|
|
59
|
+
} }
|
|
60
|
+
>
|
|
61
|
+
<MdCheckCircle aria-hidden="true" sx={ { mr: 2 } } />
|
|
62
|
+
{ title }
|
|
63
|
+
</Heading>
|
|
64
|
+
) : (
|
|
65
|
+
<Flex sx={ { alignItems: 'center', color } }>
|
|
66
|
+
<MdCheckCircle aria-hidden="true" sx={ { mr: 2 } } />
|
|
67
|
+
{ title }
|
|
68
|
+
</Flex>
|
|
69
|
+
) }
|
|
70
|
+
|
|
72
71
|
{ subTitle && active && <Text sx={ { mb: 3 } }>{ subTitle }</Text> }
|
|
73
72
|
|
|
74
73
|
{ active && children }
|
|
@@ -83,7 +82,6 @@ WizardStep.propTypes = {
|
|
|
83
82
|
order: PropTypes.number.isRequired,
|
|
84
83
|
subTitle: PropTypes.node,
|
|
85
84
|
title: PropTypes.node,
|
|
86
|
-
titleVariant: PropTypes.string,
|
|
87
85
|
};
|
|
88
86
|
|
|
89
87
|
export { WizardStep };
|
|
@@ -9,24 +9,31 @@ import PropTypes from 'prop-types';
|
|
|
9
9
|
/**
|
|
10
10
|
* Internal dependencies
|
|
11
11
|
*/
|
|
12
|
-
import { Heading } from '..';
|
|
12
|
+
import { Heading, Flex } from '..';
|
|
13
13
|
|
|
14
|
-
const WizardStepHorizontal = ( { title, active, order
|
|
15
|
-
|
|
14
|
+
const WizardStepHorizontal = ( { title, active, order } ) => {
|
|
15
|
+
const color = active ? 'heading' : 'muted';
|
|
16
|
+
|
|
17
|
+
return typeof title === 'string' ? (
|
|
16
18
|
<Heading
|
|
17
|
-
variant=
|
|
19
|
+
variant="h4"
|
|
18
20
|
sx={ {
|
|
19
21
|
mb: 0,
|
|
20
22
|
display: 'flex',
|
|
21
23
|
alignItems: 'center',
|
|
22
|
-
color
|
|
24
|
+
color,
|
|
23
25
|
} }
|
|
24
26
|
data-step={ order }
|
|
25
27
|
data-active={ active || undefined }
|
|
26
28
|
>
|
|
27
|
-
<MdCheckCircle sx={ { mr: 2 } } />
|
|
29
|
+
<MdCheckCircle aria-hidden="true" sx={ { mr: 2 } } />
|
|
28
30
|
{ title }
|
|
29
31
|
</Heading>
|
|
32
|
+
) : (
|
|
33
|
+
<Flex sx={ { alignItems: 'center', color } }>
|
|
34
|
+
<MdCheckCircle aria-hidden="true" sx={ { mr: 2 } } />
|
|
35
|
+
{ title }
|
|
36
|
+
</Flex>
|
|
30
37
|
);
|
|
31
38
|
};
|
|
32
39
|
|
|
@@ -35,7 +42,6 @@ WizardStepHorizontal.propTypes = {
|
|
|
35
42
|
order: PropTypes.number.isRequired,
|
|
36
43
|
subTitle: PropTypes.node,
|
|
37
44
|
title: PropTypes.node,
|
|
38
|
-
titleVariant: PropTypes.string,
|
|
39
45
|
};
|
|
40
46
|
|
|
41
47
|
export { WizardStepHorizontal };
|
package/src/system/index.js
CHANGED
|
@@ -44,7 +44,6 @@ import { Link } from './Link';
|
|
|
44
44
|
import { Notice } from './Notice';
|
|
45
45
|
import { Progress } from './Progress';
|
|
46
46
|
import { Spinner } from './Spinner';
|
|
47
|
-
import { ResourceList, ResourceItem } from './ResourceList';
|
|
48
47
|
import { Tooltip } from './Tooltip';
|
|
49
48
|
import { Time } from './Time';
|
|
50
49
|
import { Timeline } from './Timeline';
|
|
@@ -94,8 +93,6 @@ export {
|
|
|
94
93
|
Select,
|
|
95
94
|
Radio,
|
|
96
95
|
RadioBoxGroup,
|
|
97
|
-
ResourceList,
|
|
98
|
-
ResourceItem,
|
|
99
96
|
Textarea,
|
|
100
97
|
Progress,
|
|
101
98
|
Text,
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/** @jsxImportSource theme-ui */
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* External dependencies
|
|
5
|
-
*/
|
|
6
|
-
import PropTypes from 'prop-types';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Internal dependencies
|
|
10
|
-
*/
|
|
11
|
-
import { Box, Flex, Time } from '..';
|
|
12
|
-
|
|
13
|
-
const ResourceItem = ( {
|
|
14
|
-
children,
|
|
15
|
-
item,
|
|
16
|
-
renderActions,
|
|
17
|
-
relativeTime = false,
|
|
18
|
-
timeOnly = false,
|
|
19
|
-
dateKey,
|
|
20
|
-
icon = null,
|
|
21
|
-
} ) => {
|
|
22
|
-
return (
|
|
23
|
-
<Flex
|
|
24
|
-
sx={ {
|
|
25
|
-
alignItems: 'center',
|
|
26
|
-
gap: 3,
|
|
27
|
-
} }
|
|
28
|
-
>
|
|
29
|
-
{ icon }
|
|
30
|
-
<Box sx={ { flex: '1 1 auto' } }>{ children }</Box>
|
|
31
|
-
<Flex
|
|
32
|
-
sx={ {
|
|
33
|
-
flex: '0 0 auto',
|
|
34
|
-
alignItems: 'center',
|
|
35
|
-
gap: 3,
|
|
36
|
-
} }
|
|
37
|
-
>
|
|
38
|
-
<Time
|
|
39
|
-
className="time"
|
|
40
|
-
relativeTime={ relativeTime }
|
|
41
|
-
timeOnly={ timeOnly }
|
|
42
|
-
time={ item[ dateKey ] }
|
|
43
|
-
sx={ { color: 'muted', mb: 0, textAlign: 'right', flex: '0 0 auto' } }
|
|
44
|
-
/>
|
|
45
|
-
{ renderActions && (
|
|
46
|
-
<Flex className="actions" sx={ { alignItems: 'center', gap: 3 } }>
|
|
47
|
-
<Box sx={ { width: 4, height: 4, borderRadius: 4, bg: 'border' } } />
|
|
48
|
-
{ renderActions( item ) }
|
|
49
|
-
</Flex>
|
|
50
|
-
) }
|
|
51
|
-
</Flex>
|
|
52
|
-
</Flex>
|
|
53
|
-
);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
ResourceItem.propTypes = {
|
|
57
|
-
children: PropTypes.node,
|
|
58
|
-
item: PropTypes.object,
|
|
59
|
-
icon: PropTypes.node,
|
|
60
|
-
relativeTime: PropTypes.bool,
|
|
61
|
-
timeOnly: PropTypes.bool,
|
|
62
|
-
dateKey: PropTypes.string,
|
|
63
|
-
renderActions: PropTypes.func,
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export { ResourceItem };
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/** @jsxImportSource theme-ui */
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* External dependencies
|
|
5
|
-
*/
|
|
6
|
-
import PropTypes from 'prop-types';
|
|
7
|
-
import { useMemo } from 'react';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Internal dependencies
|
|
11
|
-
*/
|
|
12
|
-
import { Box, Heading } from '..';
|
|
13
|
-
|
|
14
|
-
const formatterOptions = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
|
|
15
|
-
|
|
16
|
-
const formatDate = date => {
|
|
17
|
-
const today = new Date();
|
|
18
|
-
if ( date.getFullYear() !== today.getFullYear() ) {
|
|
19
|
-
return date.toLocaleDateString( formatterOptions );
|
|
20
|
-
} else if ( date.getMonth() !== today.getMonth() ) {
|
|
21
|
-
return date.toLocaleDateString( formatterOptions );
|
|
22
|
-
} else if ( date.getDate() < today.getDate() - 1 ) {
|
|
23
|
-
return date.toLocaleDateString( formatterOptions );
|
|
24
|
-
} else if ( date.getDate() === today.getDate() - 1 ) {
|
|
25
|
-
return 'Yesterday';
|
|
26
|
-
}
|
|
27
|
-
return 'Today';
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const StyledListItem = props => (
|
|
31
|
-
<Box
|
|
32
|
-
as="li"
|
|
33
|
-
sx={ {
|
|
34
|
-
py: 2,
|
|
35
|
-
borderBottom: '1px solid',
|
|
36
|
-
borderColor: 'borders.2',
|
|
37
|
-
listStyleType: 'none',
|
|
38
|
-
margin: 0,
|
|
39
|
-
px: 0,
|
|
40
|
-
} }
|
|
41
|
-
{ ...props }
|
|
42
|
-
/>
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
const ResourceList = ( { groupedByDay = false, items, renderItem, dateKey } ) => {
|
|
46
|
-
let groupedItems = {};
|
|
47
|
-
if ( groupedByDay ) {
|
|
48
|
-
groupedItems = items?.reduce( ( itemGroups, item ) => {
|
|
49
|
-
const formattedDate = formatDate( item[ dateKey ] );
|
|
50
|
-
const itemsAtDate = itemGroups[ formattedDate ];
|
|
51
|
-
|
|
52
|
-
return {
|
|
53
|
-
...itemGroups,
|
|
54
|
-
[ formattedDate ]: itemsAtDate ? [ ...itemsAtDate, item ] : [ item ],
|
|
55
|
-
};
|
|
56
|
-
}, {} );
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const renderItemList = itemsList =>
|
|
60
|
-
itemsList.map( ( item, index ) => (
|
|
61
|
-
<StyledListItem key={ index }>{ renderItem( item ) }</StyledListItem>
|
|
62
|
-
) );
|
|
63
|
-
|
|
64
|
-
const renderGoupedItems = () =>
|
|
65
|
-
useMemo(
|
|
66
|
-
() =>
|
|
67
|
-
Object.keys( groupedItems ).map( ( groupName, index ) => (
|
|
68
|
-
<Box sx={ { mb: 4 } } key={ index } as="li">
|
|
69
|
-
<Heading variant="h4" as="h4" sx={ { mb: 3 } }>
|
|
70
|
-
{ groupName }
|
|
71
|
-
</Heading>
|
|
72
|
-
<Box
|
|
73
|
-
as="ul"
|
|
74
|
-
sx={ {
|
|
75
|
-
listStyleType: 'none',
|
|
76
|
-
m: 0,
|
|
77
|
-
p: 0,
|
|
78
|
-
borderTop: '1px solid',
|
|
79
|
-
borderColor: 'border',
|
|
80
|
-
} }
|
|
81
|
-
>
|
|
82
|
-
{ renderItemList( groupedItems[ groupName ] ) }
|
|
83
|
-
</Box>
|
|
84
|
-
</Box>
|
|
85
|
-
) ),
|
|
86
|
-
[ groupedItems ]
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
return (
|
|
90
|
-
<Box
|
|
91
|
-
as="ul"
|
|
92
|
-
sx={ { listStyleType: 'none', m: 0, p: 0 } }
|
|
93
|
-
className="vip-resource-list-component"
|
|
94
|
-
>
|
|
95
|
-
{ groupedByDay ? renderGoupedItems( groupedItems ) : renderItemList( items ) }
|
|
96
|
-
</Box>
|
|
97
|
-
);
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
ResourceList.propTypes = {
|
|
101
|
-
groupedByDay: PropTypes.bool,
|
|
102
|
-
items: PropTypes.array,
|
|
103
|
-
renderItem: PropTypes.func,
|
|
104
|
-
relativeTime: PropTypes.bool,
|
|
105
|
-
dateKey: PropTypes.string,
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
export { ResourceList };
|