@automattic/vip-design-system 0.9.4 → 0.10.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/.github/workflows/nodejs.yaml +1 -1
- package/README.md +4 -4
- package/build/system/Avatar/Avatar.js +9 -3
- package/build/system/Badge/Badge.js +9 -3
- package/build/system/BlankState/BlankState.js +8 -2
- package/build/system/Box/Box.js +12 -2
- package/build/system/Button/Button.js +6 -2
- package/build/system/Card/Card.js +8 -3
- package/build/system/Code/Code.js +8 -3
- package/build/system/ConfirmationDialog/ConfirmationDialog.js +8 -2
- package/build/system/Dialog/Dialog.js +1 -0
- package/build/system/Form/AsyncSearchSelect.js +38 -0
- package/build/system/Form/SearchSelect.js +47 -11
- package/build/system/Form/Select.js +22 -2
- package/build/system/Form/Select.test.js +52 -0
- package/build/system/Form/Toggle.js +8 -2
- package/build/system/Heading/Heading.js +9 -3
- package/build/system/Notice/Notice.js +9 -3
- package/build/system/Notification/Notification.js +1 -0
- package/build/system/OptionRow/OptionRow.js +13 -3
- package/build/system/OptionRow/OptionRow.test.js +46 -0
- package/build/system/Progress/Progress.js +9 -3
- package/build/system/ResourceList/ResourceList.js +1 -0
- package/build/system/Spinner/Spinner.js +9 -3
- package/build/system/Tabs/TabItem.js +1 -0
- package/build/system/Tabs/Tabs.js +10 -4
- package/build/system/Text/Text.js +9 -3
- package/build/system/Time/index.js +9 -3
- package/build/system/Timeline/Timeline.js +77 -0
- package/build/system/Timeline/index.js +2 -66
- package/build/system/Wizard/Wizard.js +10 -2
- package/build/system/Wizard/WizardStep.js +6 -2
- package/build/system/Wizard/WizardStepHorizontal.js +6 -2
- package/package.json +4 -2
- package/src/system/Avatar/Avatar.js +4 -0
- package/src/system/Badge/Badge.js +4 -1
- package/src/system/BlankState/BlankState.js +4 -1
- package/src/system/Box/Box.js +6 -1
- package/src/system/Button/Button.js +3 -0
- package/src/system/Card/Card.js +4 -1
- package/src/system/Code/Code.js +4 -1
- package/src/system/ConfirmationDialog/ConfirmationDialog.js +4 -2
- package/src/system/Dialog/Dialog.js +1 -1
- package/src/system/Form/AsyncSearchSelect.js +29 -0
- package/src/system/Form/SearchSelect.js +43 -3
- package/src/system/Form/Select.js +16 -3
- package/src/system/Form/Select.stories.js +30 -0
- package/src/system/Form/Select.test.js +37 -0
- package/src/system/Form/Toggle.js +4 -2
- package/src/system/Heading/Heading.js +4 -1
- package/src/system/Notice/Notice.js +4 -1
- package/src/system/Notification/Notification.js +1 -0
- package/src/system/OptionRow/OptionRow.js +7 -0
- package/src/system/OptionRow/OptionRow.stories.js +1 -0
- package/src/system/OptionRow/OptionRow.test.js +27 -0
- package/src/system/Progress/Progress.js +4 -1
- package/src/system/ResourceList/ResourceList.js +1 -1
- package/src/system/Spinner/Spinner.js +4 -1
- package/src/system/Tabs/TabItem.js +1 -0
- package/src/system/Tabs/Tabs.js +5 -2
- package/src/system/Text/Text.js +4 -1
- package/src/system/Time/index.js +4 -1
- package/src/system/Timeline/Timeline.js +48 -0
- package/src/system/Timeline/Timeline.stories.js +34 -0
- package/src/system/Timeline/index.js +2 -41
- package/src/system/Wizard/Wizard.js +6 -2
- package/src/system/Wizard/Wizard.stories.js +1 -1
- package/src/system/Wizard/WizardStep.js +5 -2
- package/src/system/Wizard/WizardStepHorizontal.js +4 -1
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* External dependencies
|
|
5
5
|
*/
|
|
6
|
+
import classNames from 'classnames';
|
|
6
7
|
import PropTypes from 'prop-types';
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -10,7 +11,7 @@ import PropTypes from 'prop-types';
|
|
|
10
11
|
*/
|
|
11
12
|
import { Text } from '../';
|
|
12
13
|
|
|
13
|
-
const Badge = ( { variant = 'blue', sx, ...props } ) => (
|
|
14
|
+
const Badge = ( { variant = 'blue', sx, className = null, ...props } ) => (
|
|
14
15
|
<Text
|
|
15
16
|
as="span"
|
|
16
17
|
sx={ {
|
|
@@ -26,6 +27,7 @@ const Badge = ( { variant = 'blue', sx, ...props } ) => (
|
|
|
26
27
|
fontWeight: 'heading',
|
|
27
28
|
...sx,
|
|
28
29
|
} }
|
|
30
|
+
className={ classNames( 'vip-badge-component', className ) }
|
|
29
31
|
{ ...props }
|
|
30
32
|
/>
|
|
31
33
|
);
|
|
@@ -33,6 +35,7 @@ const Badge = ( { variant = 'blue', sx, ...props } ) => (
|
|
|
33
35
|
Badge.propTypes = {
|
|
34
36
|
variant: PropTypes.string,
|
|
35
37
|
sx: PropTypes.object,
|
|
38
|
+
className: PropTypes.any,
|
|
36
39
|
};
|
|
37
40
|
|
|
38
41
|
export { Badge };
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* External dependencies
|
|
5
5
|
*/
|
|
6
|
+
import classNames from 'classnames';
|
|
6
7
|
import PropTypes from 'prop-types';
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -17,9 +18,10 @@ const BlankState = ( {
|
|
|
17
18
|
image,
|
|
18
19
|
imageAlt = 'Image representing the blank state',
|
|
19
20
|
title,
|
|
21
|
+
className = null,
|
|
20
22
|
} ) => {
|
|
21
23
|
return (
|
|
22
|
-
<Box sx={{ textAlign: 'center', padding: 5 }}>
|
|
24
|
+
<Box sx={{ textAlign: 'center', padding: 5 }} className={ classNames( 'vip-blank-state-component', className ) }>
|
|
23
25
|
{icon ? icon : <img src={image} sx={{ mb: 3 }} alt={imageAlt} />}
|
|
24
26
|
<Heading variant="h4">{title}</Heading>
|
|
25
27
|
<Text>{body}</Text>
|
|
@@ -35,6 +37,7 @@ BlankState.propTypes = {
|
|
|
35
37
|
image: PropTypes.oneOfType( [ PropTypes.object, PropTypes.string ] ),
|
|
36
38
|
imageAlt: PropTypes.string,
|
|
37
39
|
title: PropTypes.node,
|
|
40
|
+
className: PropTypes.any,
|
|
38
41
|
};
|
|
39
42
|
|
|
40
43
|
export { BlankState };
|
package/src/system/Box/Box.js
CHANGED
|
@@ -3,11 +3,16 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* External dependencies
|
|
5
5
|
*/
|
|
6
|
+
import PropTypes from 'prop-types';
|
|
7
|
+
import classNames from 'classnames';
|
|
6
8
|
import { forwardRef } from 'react';
|
|
7
9
|
import { Box as ThemeBox } from 'theme-ui';
|
|
8
10
|
|
|
9
|
-
const Box = forwardRef( ( props, ref ) => <ThemeBox ref={ref} {...props} /> );
|
|
11
|
+
const Box = forwardRef( ( props, ref ) => <ThemeBox ref={ref} className={ classNames( 'vip-box-component', props.className ) } {...props} /> );
|
|
10
12
|
|
|
11
13
|
Box.displayName = 'Box';
|
|
14
|
+
Box.propTypes = {
|
|
15
|
+
className: PropTypes.any,
|
|
16
|
+
};
|
|
12
17
|
|
|
13
18
|
export { Box };
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Button as ThemeButton } from 'theme-ui';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
|
+
import classNames from 'classnames';
|
|
8
9
|
|
|
9
10
|
const Button = ( { sx, ...props } ) => (
|
|
10
11
|
<ThemeButton
|
|
@@ -22,12 +23,14 @@ const Button = ( { sx, ...props } ) => (
|
|
|
22
23
|
},
|
|
23
24
|
...sx,
|
|
24
25
|
}}
|
|
26
|
+
className={ classNames( 'vip-button-component', props.className ) }
|
|
25
27
|
{...props}
|
|
26
28
|
/>
|
|
27
29
|
);
|
|
28
30
|
|
|
29
31
|
Button.propTypes = {
|
|
30
32
|
sx: PropTypes.object,
|
|
33
|
+
className: PropTypes.any,
|
|
31
34
|
};
|
|
32
35
|
|
|
33
36
|
export { Button };
|
package/src/system/Card/Card.js
CHANGED
|
@@ -10,8 +10,9 @@ import PropTypes from 'prop-types';
|
|
|
10
10
|
* Internal dependencies
|
|
11
11
|
*/
|
|
12
12
|
import { Box } from '..';
|
|
13
|
+
import classNames from 'classnames';
|
|
13
14
|
|
|
14
|
-
const Card = React.forwardRef( ( { variant = 'primary', sx = {}, ...props }, ref ) => {
|
|
15
|
+
const Card = React.forwardRef( ( { variant = 'primary', sx = {}, className, ...props }, ref ) => {
|
|
15
16
|
return (
|
|
16
17
|
<Box
|
|
17
18
|
ref={ref}
|
|
@@ -21,6 +22,7 @@ const Card = React.forwardRef( ( { variant = 'primary', sx = {}, ...props }, ref
|
|
|
21
22
|
overflow: 'hidden',
|
|
22
23
|
...sx,
|
|
23
24
|
}}
|
|
25
|
+
className={ classNames( 'vip-card-component', className ) }
|
|
24
26
|
{...props}
|
|
25
27
|
/>
|
|
26
28
|
);
|
|
@@ -29,6 +31,7 @@ const Card = React.forwardRef( ( { variant = 'primary', sx = {}, ...props }, ref
|
|
|
29
31
|
Card.propTypes = {
|
|
30
32
|
variant: PropTypes.string,
|
|
31
33
|
sx: PropTypes.object,
|
|
34
|
+
className: PropTypes.any,
|
|
32
35
|
};
|
|
33
36
|
|
|
34
37
|
Card.displayName = 'Card';
|
package/src/system/Code/Code.js
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* External dependencies
|
|
5
5
|
*/
|
|
6
|
+
import classNames from 'classnames';
|
|
6
7
|
import PropTypes from 'prop-types';
|
|
7
8
|
import { useRef, useState } from 'react';
|
|
8
9
|
import { MdContentCopy } from 'react-icons/md';
|
|
9
10
|
|
|
10
|
-
const Code = ( { prompt = false, showCopy = false, onCopy = null, ...props } ) => {
|
|
11
|
+
const Code = ( { prompt = false, showCopy = false, onCopy = null, className, ...props } ) => {
|
|
11
12
|
const ref = useRef();
|
|
12
13
|
|
|
13
14
|
const codeDom = (
|
|
@@ -29,6 +30,7 @@ const Code = ( { prompt = false, showCopy = false, onCopy = null, ...props } ) =
|
|
|
29
30
|
userSelect: 'none',
|
|
30
31
|
},
|
|
31
32
|
} }
|
|
33
|
+
className={ classNames( 'vip-code-component', className ) }
|
|
32
34
|
{ ...props }
|
|
33
35
|
/>
|
|
34
36
|
);
|
|
@@ -88,6 +90,7 @@ Code.propTypes = {
|
|
|
88
90
|
prompt: PropTypes.bool,
|
|
89
91
|
showCopy: PropTypes.bool,
|
|
90
92
|
onCopy: PropTypes.func,
|
|
93
|
+
className: PropTypes.any,
|
|
91
94
|
};
|
|
92
95
|
|
|
93
96
|
export { Code };
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* External dependencies
|
|
5
5
|
*/
|
|
6
|
+
import classNames from 'classnames';
|
|
6
7
|
import PropTypes from 'prop-types';
|
|
7
8
|
import React from 'react';
|
|
8
9
|
|
|
@@ -11,8 +12,8 @@ import React from 'react';
|
|
|
11
12
|
*/
|
|
12
13
|
import { Dialog, Box, Heading, Text, Flex, Button } from '../';
|
|
13
14
|
|
|
14
|
-
const ConfirmationDialogContent = ( { title, body, onClose, label = 'Confirm', onConfirm } ) => (
|
|
15
|
-
<Box p={ 4 }>
|
|
15
|
+
const ConfirmationDialogContent = ( { title, body, onClose, label = 'Confirm', onConfirm, className = null } ) => (
|
|
16
|
+
<Box p={ 4 } className={ classNames( 'vip-confirmation-dialog-component', className ) }>
|
|
16
17
|
<Heading variant="h3" sx={ { mb: 2 } }>
|
|
17
18
|
{ title }
|
|
18
19
|
</Heading>
|
|
@@ -40,6 +41,7 @@ ConfirmationDialogContent.propTypes = {
|
|
|
40
41
|
label: PropTypes.string,
|
|
41
42
|
onClose: PropTypes.func,
|
|
42
43
|
onConfirm: PropTypes.func,
|
|
44
|
+
className: PropTypes.any,
|
|
43
45
|
};
|
|
44
46
|
|
|
45
47
|
const ConfirmationDialog = ( { trigger, onConfirm, needsConfirm = true, ...props } ) => {
|
|
@@ -46,7 +46,7 @@ const Dialog = ( { trigger, position = 'left', startOpen = false, content, disab
|
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
return (
|
|
49
|
-
<div onClick={ e => e.stopPropagation() } sx={ { position: 'relative' } } ref={ dialogRef }>
|
|
49
|
+
<div onClick={ e => e.stopPropagation() } sx={ { position: 'relative' } } ref={ dialogRef } className="vip-dialog-component">
|
|
50
50
|
<DialogTrigger
|
|
51
51
|
tabIndex="0"
|
|
52
52
|
sx={ { display: 'inline' } }
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** @jsxImportSource theme-ui */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* External dependencies
|
|
5
|
+
*/
|
|
6
|
+
import PropTypes from 'prop-types';
|
|
7
|
+
import { withAsyncPaginate } from 'react-select-async-paginate';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Internal dependencies
|
|
11
|
+
*/
|
|
12
|
+
import { SearchSelect } from './SearchSelect';
|
|
13
|
+
|
|
14
|
+
// Asynchronous search select to load paginated results asynchronously
|
|
15
|
+
const CustomAsyncPaginate = withAsyncPaginate( SearchSelect );
|
|
16
|
+
|
|
17
|
+
const AsyncSearchSelect = ( { options, ...props } ) => (
|
|
18
|
+
<CustomAsyncPaginate
|
|
19
|
+
SelectComponent={ SearchSelect }
|
|
20
|
+
loadOptions={ options }
|
|
21
|
+
{ ...props }
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
AsyncSearchSelect.propTypes = {
|
|
26
|
+
options: PropTypes.array,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export { AsyncSearchSelect };
|
|
@@ -12,6 +12,7 @@ import PropTypes from 'prop-types';
|
|
|
12
12
|
*/
|
|
13
13
|
import { Flex, Text } from '..';
|
|
14
14
|
|
|
15
|
+
// Option component
|
|
15
16
|
export const Option = ( { label, isSelected, ...props } ) => (
|
|
16
17
|
<components.Option {...props}>
|
|
17
18
|
<Flex sx={{ alignItems: 'center' }}>
|
|
@@ -32,7 +33,45 @@ Option.propTypes = {
|
|
|
32
33
|
isSelected: PropTypes.bool,
|
|
33
34
|
};
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
// DropdownIndicator component
|
|
37
|
+
export const DropdownIndicator = ( {
|
|
38
|
+
innerProps,
|
|
39
|
+
isFocused,
|
|
40
|
+
isDisabled,
|
|
41
|
+
clearValue,
|
|
42
|
+
cx,
|
|
43
|
+
getStyles,
|
|
44
|
+
getValue,
|
|
45
|
+
hasValue,
|
|
46
|
+
isMulti,
|
|
47
|
+
isRtl,
|
|
48
|
+
options,
|
|
49
|
+
selectProps,
|
|
50
|
+
setValue,
|
|
51
|
+
selectOption,
|
|
52
|
+
theme,
|
|
53
|
+
...props
|
|
54
|
+
} ) => <MdExpandMore { ...props } sx={ { color: 'text', mr: 2 } } />;
|
|
55
|
+
|
|
56
|
+
DropdownIndicator.propTypes = {
|
|
57
|
+
innerProps: PropTypes.object,
|
|
58
|
+
isFocused: PropTypes.bool,
|
|
59
|
+
isDisabled: PropTypes.bool,
|
|
60
|
+
clearValue: PropTypes.func,
|
|
61
|
+
cx: PropTypes.func,
|
|
62
|
+
getStyles: PropTypes.func,
|
|
63
|
+
getValue: PropTypes.func,
|
|
64
|
+
hasValue: PropTypes.bool,
|
|
65
|
+
isMulti: PropTypes.bool,
|
|
66
|
+
isRtl: PropTypes.bool,
|
|
67
|
+
options: PropTypes.array,
|
|
68
|
+
selectProps: PropTypes.object,
|
|
69
|
+
setValue: PropTypes.func,
|
|
70
|
+
selectOption: PropTypes.func,
|
|
71
|
+
theme: PropTypes.object,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// ClearIndicator component
|
|
36
75
|
const ClearIndicator = ( { innerProps: { ref, ...restInnerProps }, ...props } ) => (
|
|
37
76
|
<MdClose ref={ref} {...restInnerProps} {...props} sx={{ color: 'text', mr: 2 }} />
|
|
38
77
|
);
|
|
@@ -41,11 +80,12 @@ ClearIndicator.propTypes = {
|
|
|
41
80
|
innerProps: PropTypes.object,
|
|
42
81
|
};
|
|
43
82
|
|
|
83
|
+
// Parent SearchSelect component
|
|
44
84
|
const SearchSelect = props => (
|
|
45
85
|
<Select
|
|
46
|
-
{...props}
|
|
86
|
+
{ ...props }
|
|
47
87
|
classNamePrefix={ 'select' }
|
|
48
|
-
components={{ Option, DropdownIndicator, ClearIndicator }}
|
|
88
|
+
components={ { Option, DropdownIndicator, ClearIndicator } }
|
|
49
89
|
sx={ {
|
|
50
90
|
'.select__control': {
|
|
51
91
|
background: 'none',
|
|
@@ -11,8 +11,10 @@ import PropTypes from 'prop-types';
|
|
|
11
11
|
*/
|
|
12
12
|
import { SearchSelect } from './SearchSelect';
|
|
13
13
|
import { InlineSelect } from './InlineSelect';
|
|
14
|
+
import { AsyncSearchSelect } from './AsyncSearchSelect';
|
|
14
15
|
|
|
15
|
-
const Select = ( { isMulti = false, isInline, options, label, isSearch, usePortal, ...props } ) => {
|
|
16
|
+
const Select = ( { isMulti = false, isInline, isAsync, options, label, isSearch, usePortal, ...props } ) => {
|
|
17
|
+
let Component;
|
|
16
18
|
const selectRef = React.useRef();
|
|
17
19
|
const portalProps = {};
|
|
18
20
|
|
|
@@ -22,14 +24,25 @@ const Select = ( { isMulti = false, isInline, options, label, isSearch, usePorta
|
|
|
22
24
|
portalProps.styles = { menuPortal: base => ( { ...base, position: 'fixed' } ) };
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
switch ( true ) {
|
|
28
|
+
case isInline:
|
|
29
|
+
Component = InlineSelect;
|
|
30
|
+
break;
|
|
31
|
+
case isAsync:
|
|
32
|
+
Component = AsyncSearchSelect;
|
|
33
|
+
break;
|
|
34
|
+
default:
|
|
35
|
+
Component = SearchSelect;
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
26
38
|
|
|
27
|
-
return <div ref={selectRef}><Component isMulti={isMulti} label={label} options={options} {...portalProps} {...props} /></div>;
|
|
39
|
+
return <div ref={selectRef} className="vip-select-component"><Component isMulti={isMulti} label={label} options={options} {...portalProps} {...props} /></div>;
|
|
28
40
|
};
|
|
29
41
|
|
|
30
42
|
Select.propTypes = {
|
|
31
43
|
isInline: PropTypes.bool,
|
|
32
44
|
isMulti: PropTypes.bool,
|
|
45
|
+
isAsync: PropTypes.bool,
|
|
33
46
|
isSearch: PropTypes.bool,
|
|
34
47
|
label: PropTypes.string,
|
|
35
48
|
options: PropTypes.array,
|
|
@@ -105,6 +105,36 @@ export const Inline = () => {
|
|
|
105
105
|
);
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
+
export const Async = () => {
|
|
109
|
+
const [ value, setValue ] = useState( [] );
|
|
110
|
+
const loadOptions = async () => new Promise( resolve => {
|
|
111
|
+
setTimeout( () => {
|
|
112
|
+
resolve( {
|
|
113
|
+
options: [
|
|
114
|
+
...options,
|
|
115
|
+
{ value: 'newvanilla', label: 'New Vanilla' },
|
|
116
|
+
],
|
|
117
|
+
} );
|
|
118
|
+
}, 2000 );
|
|
119
|
+
} );
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<Box sx={{ mr: 2, width: 200 }}>
|
|
123
|
+
<Select
|
|
124
|
+
label="Async Select"
|
|
125
|
+
value={value}
|
|
126
|
+
isAsync
|
|
127
|
+
usePortal
|
|
128
|
+
loadOptions={ loadOptions }
|
|
129
|
+
noneLabel="Everyone"
|
|
130
|
+
placeholder="Load async..."
|
|
131
|
+
options={options}
|
|
132
|
+
onChange={newValue => setValue( newValue )}
|
|
133
|
+
/>
|
|
134
|
+
</Box>
|
|
135
|
+
);
|
|
136
|
+
};
|
|
137
|
+
|
|
108
138
|
export const DropdownMenu = () => {
|
|
109
139
|
return (
|
|
110
140
|
<Box sx={{ mr: 2, width: 200 }}>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
import { axe } from 'jest-axe';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Internal dependencies
|
|
9
|
+
*/
|
|
10
|
+
import { Select } from './Select';
|
|
11
|
+
|
|
12
|
+
describe( '<Select />', () => {
|
|
13
|
+
it( 'renders the Select component with the specified placeholder', () => {
|
|
14
|
+
render(
|
|
15
|
+
<Select
|
|
16
|
+
inputId={ 'search-select' }
|
|
17
|
+
placeholder={ 'Search...' }
|
|
18
|
+
/>
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
// Can't use `getByPlaceholderText` here since it's not actually being rendered as a placeholder element
|
|
22
|
+
const placeholder = screen.getByText( 'Search...' );
|
|
23
|
+
|
|
24
|
+
expect( placeholder ).toBeInTheDocument();
|
|
25
|
+
} );
|
|
26
|
+
|
|
27
|
+
it( 'renders the Select component with accessibility props', async () => {
|
|
28
|
+
const { container } = render(
|
|
29
|
+
<Select
|
|
30
|
+
inputId={ 'search-select' }
|
|
31
|
+
aria-label={ 'Search or select from the dropdown list' }
|
|
32
|
+
/>
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
expect( await axe( container ) ).toHaveNoViolations();
|
|
36
|
+
} );
|
|
37
|
+
} );
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* External dependencies
|
|
5
5
|
*/
|
|
6
|
+
import classNames from 'classnames';
|
|
6
7
|
import PropTypes from 'prop-types';
|
|
7
8
|
|
|
8
|
-
const Toggle = ( { name = 'toggle', ...props } ) => (
|
|
9
|
-
<CheckBoxWrapper>
|
|
9
|
+
const Toggle = ( { name = 'toggle', className = null, ...props } ) => (
|
|
10
|
+
<CheckBoxWrapper className={ classNames( 'vip-checkbox-component', className ) }>
|
|
10
11
|
<CheckBox name={name} id={name} type="checkbox" {...props} />
|
|
11
12
|
<CheckBoxLabel htmlFor={name} />
|
|
12
13
|
</CheckBoxWrapper>
|
|
@@ -14,6 +15,7 @@ const Toggle = ( { name = 'toggle', ...props } ) => (
|
|
|
14
15
|
|
|
15
16
|
Toggle.propTypes = {
|
|
16
17
|
name: PropTypes.string,
|
|
18
|
+
className: PropTypes.any,
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
export { Toggle };
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Heading as ThemeHeading } from 'theme-ui';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
|
+
import classNames from 'classnames';
|
|
8
9
|
|
|
9
|
-
const Heading = ( { variant = 'h3', sx, ...props } ) => (
|
|
10
|
+
const Heading = ( { variant = 'h3', sx, className = null, ...props } ) => (
|
|
10
11
|
<ThemeHeading
|
|
11
12
|
as={variant}
|
|
12
13
|
sx={{
|
|
@@ -15,6 +16,7 @@ const Heading = ( { variant = 'h3', sx, ...props } ) => (
|
|
|
15
16
|
variant: `text.${ variant }`,
|
|
16
17
|
...sx,
|
|
17
18
|
}}
|
|
19
|
+
className={ classNames( 'vip-heading-component', className ) }
|
|
18
20
|
{...props}
|
|
19
21
|
/>
|
|
20
22
|
);
|
|
@@ -22,6 +24,7 @@ const Heading = ( { variant = 'h3', sx, ...props } ) => (
|
|
|
22
24
|
Heading.propTypes = {
|
|
23
25
|
variant: PropTypes.string,
|
|
24
26
|
sx: PropTypes.object,
|
|
27
|
+
className: PropTypes.any,
|
|
25
28
|
};
|
|
26
29
|
|
|
27
30
|
export { Heading };
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* External dependencies
|
|
5
5
|
*/
|
|
6
|
+
import classNames from 'classnames';
|
|
6
7
|
import PropTypes from 'prop-types';
|
|
7
8
|
import { MdError, MdWarning, MdCheckCircle, MdInfo } from 'react-icons/md';
|
|
8
9
|
|
|
@@ -36,7 +37,7 @@ NoticeIcon.propTypes = {
|
|
|
36
37
|
variant: PropTypes.string,
|
|
37
38
|
};
|
|
38
39
|
|
|
39
|
-
const Notice = ( { variant = 'warning', inline = false, children, title, sx = {}, ...props } ) => {
|
|
40
|
+
const Notice = ( { variant = 'warning', inline = false, children, title, sx = {}, className = null, ...props } ) => {
|
|
40
41
|
let color = 'yellow';
|
|
41
42
|
|
|
42
43
|
switch ( variant ) {
|
|
@@ -66,6 +67,7 @@ const Notice = ( { variant = 'warning', inline = false, children, title, sx = {}
|
|
|
66
67
|
},
|
|
67
68
|
...sx,
|
|
68
69
|
} }
|
|
70
|
+
className={ classNames( 'vip-notice-component', className ) }
|
|
69
71
|
{ ...props }
|
|
70
72
|
>
|
|
71
73
|
<Flex sx={ {
|
|
@@ -93,6 +95,7 @@ Notice.propTypes = {
|
|
|
93
95
|
sx: PropTypes.object,
|
|
94
96
|
title: PropTypes.node,
|
|
95
97
|
variant: PropTypes.string,
|
|
98
|
+
className: PropTypes.any,
|
|
96
99
|
};
|
|
97
100
|
|
|
98
101
|
export { Notice };
|
|
@@ -11,6 +11,7 @@ import PropTypes from 'prop-types';
|
|
|
11
11
|
* Internal dependencies
|
|
12
12
|
*/
|
|
13
13
|
import { Badge, Box, Grid, Heading, Text } from '..';
|
|
14
|
+
import classNames from 'classnames';
|
|
14
15
|
|
|
15
16
|
const OptionRow = ( {
|
|
16
17
|
image,
|
|
@@ -24,6 +25,8 @@ const OptionRow = ( {
|
|
|
24
25
|
to,
|
|
25
26
|
small = false,
|
|
26
27
|
disabled = false,
|
|
28
|
+
order = null,
|
|
29
|
+
className = null,
|
|
27
30
|
...props
|
|
28
31
|
} ) => {
|
|
29
32
|
const mergedCard = disabled
|
|
@@ -53,6 +56,8 @@ const OptionRow = ( {
|
|
|
53
56
|
to={to}
|
|
54
57
|
columns={[ 1, 1, 'auto 1fr auto' ]}
|
|
55
58
|
gap={[ 3, 3, `${ small ? 3 : 4 }` ]}
|
|
59
|
+
data-order={ order || undefined }
|
|
60
|
+
className={ classNames( 'vip-option-row-component', className ) }
|
|
56
61
|
{...props}
|
|
57
62
|
sx={{
|
|
58
63
|
alignItems: 'center',
|
|
@@ -119,6 +124,8 @@ OptionRow.propTypes = {
|
|
|
119
124
|
to: PropTypes.string,
|
|
120
125
|
small: PropTypes.bool,
|
|
121
126
|
disabled: PropTypes.bool,
|
|
127
|
+
order: PropTypes.number,
|
|
128
|
+
className: PropTypes.any,
|
|
122
129
|
};
|
|
123
130
|
|
|
124
131
|
export { OptionRow };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
import { axe } from 'jest-axe';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Internal dependencies
|
|
9
|
+
*/
|
|
10
|
+
import { OptionRow } from './OptionRow';
|
|
11
|
+
|
|
12
|
+
describe( '<OptionRow />', () => {
|
|
13
|
+
it( 'renders the OptionRow', async () => {
|
|
14
|
+
const { container } = render(
|
|
15
|
+
<OptionRow
|
|
16
|
+
label="Option Row"
|
|
17
|
+
subTitle="Mostly used to link off to other pages."
|
|
18
|
+
as="a"
|
|
19
|
+
/>
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
expect( screen.getByText( 'Mostly used to link off to other pages.' ) ).toBeInTheDocument();
|
|
23
|
+
|
|
24
|
+
// Check for accessibility issues
|
|
25
|
+
await expect( await axe( container ) ).toHaveNoViolations();
|
|
26
|
+
} );
|
|
27
|
+
} );
|
|
@@ -11,10 +11,12 @@ import PropTypes from 'prop-types';
|
|
|
11
11
|
*/
|
|
12
12
|
import { Spinner } from '../Spinner';
|
|
13
13
|
import { Box, Heading, Text, Flex } from '../';
|
|
14
|
+
import classNames from 'classnames';
|
|
14
15
|
|
|
15
|
-
const Progress = ( { steps, activeStep, sx, ...props } ) => (
|
|
16
|
+
const Progress = ( { steps, activeStep, sx, className, ...props } ) => (
|
|
16
17
|
<Box>
|
|
17
18
|
<ThemeProgress
|
|
19
|
+
className={ classNames( 'vip-progress-component', className ) }
|
|
18
20
|
{ ...props }
|
|
19
21
|
sx={ {
|
|
20
22
|
color: 'primary',
|
|
@@ -39,6 +41,7 @@ Progress.propTypes = {
|
|
|
39
41
|
steps: PropTypes.array,
|
|
40
42
|
activeStep: PropTypes.number,
|
|
41
43
|
sx: PropTypes.object,
|
|
44
|
+
className: PropTypes.any,
|
|
42
45
|
};
|
|
43
46
|
|
|
44
47
|
export { Progress };
|
|
@@ -59,7 +59,7 @@ const ResourceList = ( { groupedByDay = false, items, renderItem, dateKey } ) =>
|
|
|
59
59
|
itemsList.map( ( item, index ) => <StyledListItem key={index}>{renderItem( item )}</StyledListItem> );
|
|
60
60
|
|
|
61
61
|
return (
|
|
62
|
-
<Box as="ul" sx={{ listStyleType: 'none', m: 0, p: 0 }}>
|
|
62
|
+
<Box as="ul" sx={{ listStyleType: 'none', m: 0, p: 0 }} className="vip-resource-list-component">
|
|
63
63
|
{groupedByDay
|
|
64
64
|
? Object.keys( groupedItems ).map( ( groupName, index ) => (
|
|
65
65
|
<Box sx={{ mb: 4 }} key={index}>
|
|
@@ -5,20 +5,23 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Spinner as ThemeSpinner } from 'theme-ui';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
|
+
import classNames from 'classnames';
|
|
8
9
|
|
|
9
|
-
const Spinner = ( { sx, ...props } ) => (
|
|
10
|
+
const Spinner = ( { sx, className = null, ...props } ) => (
|
|
10
11
|
<ThemeSpinner
|
|
11
12
|
strokeWidth={2}
|
|
12
13
|
sx={{
|
|
13
14
|
fill: 'none',
|
|
14
15
|
color: 'primary',
|
|
15
16
|
}}
|
|
17
|
+
className={ classNames( 'vip-spinner-component', className ) }
|
|
16
18
|
{...props}
|
|
17
19
|
/>
|
|
18
20
|
);
|
|
19
21
|
|
|
20
22
|
Spinner.propTypes = {
|
|
21
23
|
sx: PropTypes.object,
|
|
24
|
+
className: PropTypes.any,
|
|
22
25
|
};
|
|
23
26
|
|
|
24
27
|
export { Spinner };
|
package/src/system/Tabs/Tabs.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* External dependencies
|
|
5
5
|
*/
|
|
6
|
+
import classNames from 'classnames';
|
|
6
7
|
import PropTypes from 'prop-types';
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -10,8 +11,9 @@ import PropTypes from 'prop-types';
|
|
|
10
11
|
*/
|
|
11
12
|
import { Flex } from '..';
|
|
12
13
|
|
|
13
|
-
const Tabs = ( { sx, ...props } ) => (
|
|
14
|
+
const Tabs = ( { className = null, sx, ...props } ) => (
|
|
14
15
|
<Flex
|
|
16
|
+
className={ classNames( 'vip-tabs-component', className ) }
|
|
15
17
|
sx={{
|
|
16
18
|
borderBottom: '1px solid',
|
|
17
19
|
borderColor: 'border',
|
|
@@ -25,8 +27,9 @@ const Tabs = ( { sx, ...props } ) => (
|
|
|
25
27
|
);
|
|
26
28
|
|
|
27
29
|
Tabs.propTypes = {
|
|
28
|
-
|
|
30
|
+
className: PropTypes.any,
|
|
29
31
|
sx: PropTypes.object,
|
|
32
|
+
variant: PropTypes.string,
|
|
30
33
|
};
|
|
31
34
|
|
|
32
35
|
export { Tabs };
|