@punch-in/buffet-modern-core 3.3.11
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 +50 -0
- package/babel.config.js +18 -0
- package/build/bundle.development.js +850 -0
- package/build/bundle.production.js +1 -0
- package/build/esm/components/AttributeIcon/Div.js +51 -0
- package/build/esm/components/AttributeIcon/index.js +53 -0
- package/build/esm/components/Button/index.js +75 -0
- package/build/esm/components/Checkbox/index.js +78 -0
- package/build/esm/components/Count/Wrapper.js +32 -0
- package/build/esm/components/Count/index.js +27 -0
- package/build/esm/components/DatePicker/index.js +206 -0
- package/build/esm/components/DatePicker/reducer.js +42 -0
- package/build/esm/components/Enumeration/index.js +54 -0
- package/build/esm/components/Error/index.js +137 -0
- package/build/esm/components/Error/reducer.js +23 -0
- package/build/esm/components/Flex/index.js +29 -0
- package/build/esm/components/HeaderActions/index.js +41 -0
- package/build/esm/components/HeaderTitle/index.js +45 -0
- package/build/esm/components/Icon/index.js +26 -0
- package/build/esm/components/IconLinks/index.js +36 -0
- package/build/esm/components/InputNumber/index.js +70 -0
- package/build/esm/components/InputText/PrefixIcon.js +32 -0
- package/build/esm/components/InputText/index.js +89 -0
- package/build/esm/components/Label/index.js +40 -0
- package/build/esm/components/List/index.js +50 -0
- package/build/esm/components/ListHeader/BaselineAlignement.js +5 -0
- package/build/esm/components/ListHeader/index.js +52 -0
- package/build/esm/components/ListRow/index.js +30 -0
- package/build/esm/components/ListRow/tests/index.tests.js +21 -0
- package/build/esm/components/NavTabs/index.js +38 -0
- package/build/esm/components/Option/RemoveButton.js +5 -0
- package/build/esm/components/Option/index.js +32 -0
- package/build/esm/components/Padded/index.js +56 -0
- package/build/esm/components/Paging/index.js +57 -0
- package/build/esm/components/Picker/PickerButton.js +61 -0
- package/build/esm/components/Picker/PickerSection.js +48 -0
- package/build/esm/components/Picker/PickerWrapper.js +5 -0
- package/build/esm/components/Picker/index.js +50 -0
- package/build/esm/components/PrefixIcon/index.js +7 -0
- package/build/esm/components/Select/index.js +82 -0
- package/build/esm/components/Separator/index.js +44 -0
- package/build/esm/components/Table/ActionCollapse.js +40 -0
- package/build/esm/components/Table/index.js +140 -0
- package/build/esm/components/Table/tests/index.js +130 -0
- package/build/esm/components/TableHeader/index.js +88 -0
- package/build/esm/components/TableRow/index.js +93 -0
- package/build/esm/components/Text/index.js +67 -0
- package/build/esm/components/Textarea/index.js +16 -0
- package/build/esm/components/TimePicker/index.js +288 -0
- package/build/esm/components/Toggle/index.js +72 -0
- package/build/esm/components/UnknownInput/index.js +19 -0
- package/build/esm/index.js +33 -0
- package/build/esm/theme/colors.js +48 -0
- package/build/index.js +8 -0
- package/package.json +123 -0
- package/src/components/AttributeIcon/Div.js +63 -0
- package/src/components/AttributeIcon/index.js +72 -0
- package/src/components/Button/index.js +95 -0
- package/src/components/Checkbox/index.js +86 -0
- package/src/components/Checkbox/tests/Checkbox.test.js +49 -0
- package/src/components/Count/Wrapper.js +36 -0
- package/src/components/Count/index.js +30 -0
- package/src/components/DatePicker/index.js +213 -0
- package/src/components/DatePicker/reducer.js +27 -0
- package/src/components/DatePicker/tests/__snapshots__/index.test.js.snap +301 -0
- package/src/components/DatePicker/tests/index.test.js +111 -0
- package/src/components/Enumeration/index.js +71 -0
- package/src/components/Enumeration/tests/index.test.js +41 -0
- package/src/components/Error/index.js +118 -0
- package/src/components/Error/reducer.js +14 -0
- package/src/components/Flex/index.js +25 -0
- package/src/components/Flex/tests/__snapshots__/index.test.js.snap +28 -0
- package/src/components/Flex/tests/index.test.js +11 -0
- package/src/components/HeaderActions/index.js +52 -0
- package/src/components/HeaderActions/tests/index.test.js +15 -0
- package/src/components/HeaderTitle/index.js +59 -0
- package/src/components/HeaderTitle/tests/index.test.js +15 -0
- package/src/components/Icon/index.js +50 -0
- package/src/components/Icon/tests/Icon.test.js +33 -0
- package/src/components/IconLinks/index.js +39 -0
- package/src/components/IconLinks/tests/index.test.js +27 -0
- package/src/components/InputNumber/index.js +74 -0
- package/src/components/InputText/PrefixIcon.js +38 -0
- package/src/components/InputText/index.js +88 -0
- package/src/components/Label/index.js +53 -0
- package/src/components/Label/tests/Label.test.js +38 -0
- package/src/components/List/index.js +56 -0
- package/src/components/List/tests/index.test.js +19 -0
- package/src/components/ListHeader/BaselineAlignement.js +7 -0
- package/src/components/ListHeader/index.js +58 -0
- package/src/components/ListHeader/tests/index.test.js +11 -0
- package/src/components/ListRow/index.js +34 -0
- package/src/components/ListRow/tests/index.tests.js +32 -0
- package/src/components/NavTabs/index.js +51 -0
- package/src/components/Option/RemoveButton.js +18 -0
- package/src/components/Option/index.js +32 -0
- package/src/components/Padded/index.js +47 -0
- package/src/components/Padded/tests/__snapshots__/index.test.js.snap +8 -0
- package/src/components/Padded/tests/index.test.js +11 -0
- package/src/components/Paging/index.js +66 -0
- package/src/components/Picker/PickerButton.js +84 -0
- package/src/components/Picker/PickerSection.js +41 -0
- package/src/components/Picker/PickerWrapper.js +7 -0
- package/src/components/Picker/index.js +44 -0
- package/src/components/Picker/tests/__snapshots__/pickerButton.test.js.snap +54 -0
- package/src/components/Picker/tests/__snapshots__/pickerSection.test.js.snap +20 -0
- package/src/components/Picker/tests/pickerButton.test.js +11 -0
- package/src/components/Picker/tests/pickerSection.test.js +11 -0
- package/src/components/PrefixIcon/index.js +11 -0
- package/src/components/Select/index.js +110 -0
- package/src/components/Select/tests/index.test.js +85 -0
- package/src/components/Separator/index.js +49 -0
- package/src/components/Table/ActionCollapse.js +53 -0
- package/src/components/Table/index.js +172 -0
- package/src/components/Table/tests/index.js +146 -0
- package/src/components/TableHeader/index.js +103 -0
- package/src/components/TableHeader/tests/index.test.js +85 -0
- package/src/components/TableRow/index.js +116 -0
- package/src/components/TableRow/tests/index.test.js +89 -0
- package/src/components/Text/index.js +62 -0
- package/src/components/Text/tests/__snapshots__/index.test.js.snap +19 -0
- package/src/components/Text/tests/index.test.js +11 -0
- package/src/components/Textarea/index.js +19 -0
- package/src/components/Textarea/tests/index.test.js +23 -0
- package/src/components/TimePicker/index.js +328 -0
- package/src/components/TimePicker/tests/index.test.js +95 -0
- package/src/components/Toggle/index.js +83 -0
- package/src/components/Toggle/tests/index.test.js +40 -0
- package/src/components/UnknownInput/index.js +20 -0
- package/src/index.js +33 -0
- package/src/theme/colors.js +48 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { mount } from 'enzyme';
|
|
3
|
+
|
|
4
|
+
import Enumeration from '../index';
|
|
5
|
+
|
|
6
|
+
const defaultProps = {
|
|
7
|
+
name: 'enumeration',
|
|
8
|
+
type: 'radio',
|
|
9
|
+
options: [
|
|
10
|
+
{
|
|
11
|
+
value: 'first',
|
|
12
|
+
label: 'first option',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
value: 'second',
|
|
16
|
+
label: 'second option',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
value: 'third',
|
|
20
|
+
label: 'third option',
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
const renderComponent = (props = defaultProps) =>
|
|
25
|
+
mount(<Enumeration {...props} />);
|
|
26
|
+
|
|
27
|
+
describe('<Enumeration />', () => {
|
|
28
|
+
// eslint-disable-next-line jest/expect-expect
|
|
29
|
+
it('should not crash', () => {
|
|
30
|
+
renderComponent();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should use the defaultProps', () => {
|
|
34
|
+
const {
|
|
35
|
+
defaultProps: { onChange },
|
|
36
|
+
} = Enumeration;
|
|
37
|
+
|
|
38
|
+
expect(onChange).toBeDefined();
|
|
39
|
+
expect(onChange({ preventDefault: jest.fn() })).toBe(undefined);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Error
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React, { useEffect, useReducer, useRef } from 'react';
|
|
8
|
+
import PropTypes from 'prop-types';
|
|
9
|
+
import { isEmpty } from 'lodash';
|
|
10
|
+
|
|
11
|
+
import { createYupSchema } from '@punch-in/buffet-modern-utils';
|
|
12
|
+
import reducer from './reducer';
|
|
13
|
+
|
|
14
|
+
function Error({
|
|
15
|
+
children,
|
|
16
|
+
inputError,
|
|
17
|
+
translatedErrors,
|
|
18
|
+
type,
|
|
19
|
+
validations,
|
|
20
|
+
value,
|
|
21
|
+
}) {
|
|
22
|
+
const [state, dispatch] = useReducer(reducer, {
|
|
23
|
+
error: false,
|
|
24
|
+
canCheck: !isEmpty(value),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const ref = useRef();
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
dispatch({
|
|
31
|
+
type: 'SET_ERROR',
|
|
32
|
+
error: inputError,
|
|
33
|
+
});
|
|
34
|
+
}, [inputError]);
|
|
35
|
+
|
|
36
|
+
const { error, canCheck } = state;
|
|
37
|
+
|
|
38
|
+
const resetError = () => {
|
|
39
|
+
if (!ref.current) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
dispatch({
|
|
44
|
+
type: 'SET_ERROR',
|
|
45
|
+
error: null,
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const setError = message => {
|
|
50
|
+
if (!ref.current) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
dispatch({
|
|
55
|
+
type: 'SET_ERROR',
|
|
56
|
+
error: message,
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const handleBlur = async ({ target }) => {
|
|
61
|
+
if (canCheck) {
|
|
62
|
+
try {
|
|
63
|
+
await createYupSchema(type, validations, translatedErrors).validate(
|
|
64
|
+
target.value
|
|
65
|
+
);
|
|
66
|
+
resetError();
|
|
67
|
+
} catch (err) {
|
|
68
|
+
const { message } = err;
|
|
69
|
+
setError(message);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
if (children) {
|
|
75
|
+
return (
|
|
76
|
+
<>
|
|
77
|
+
{children({
|
|
78
|
+
canCheck,
|
|
79
|
+
dispatch,
|
|
80
|
+
error,
|
|
81
|
+
onBlur: handleBlur,
|
|
82
|
+
})}
|
|
83
|
+
<span style={{ display: 'none' }} ref={ref} />
|
|
84
|
+
</>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
Error.defaultProps = {
|
|
90
|
+
children: () => {},
|
|
91
|
+
translatedErrors: {
|
|
92
|
+
date: 'This is not a date',
|
|
93
|
+
email: 'This is not an email',
|
|
94
|
+
string: 'This is not a string',
|
|
95
|
+
number: 'This is not a number',
|
|
96
|
+
json: 'This is not a JSON',
|
|
97
|
+
max: 'This is too high',
|
|
98
|
+
maxLength: 'This is too long',
|
|
99
|
+
min: 'This is too small',
|
|
100
|
+
minLength: 'This is too short',
|
|
101
|
+
required: 'This value is required',
|
|
102
|
+
regex: 'This does not match the format',
|
|
103
|
+
uppercase: 'This must be a upper case string',
|
|
104
|
+
},
|
|
105
|
+
type: null,
|
|
106
|
+
validations: {},
|
|
107
|
+
value: null,
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
Error.propTypes = {
|
|
111
|
+
children: PropTypes.func,
|
|
112
|
+
translatedErrors: PropTypes.objectOf(PropTypes.string),
|
|
113
|
+
type: PropTypes.string,
|
|
114
|
+
validations: PropTypes.objectOf(PropTypes.any),
|
|
115
|
+
value: PropTypes.any, // eslint-disable-line react/forbid-prop-types
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export default Error;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
function reducer(state, action) {
|
|
2
|
+
const { error, type } = action;
|
|
3
|
+
|
|
4
|
+
switch (type) {
|
|
5
|
+
case 'SET_ERROR':
|
|
6
|
+
return { ...state, error };
|
|
7
|
+
case 'SET_CHECK':
|
|
8
|
+
return { ...state, canCheck: true };
|
|
9
|
+
default:
|
|
10
|
+
return state;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default reducer;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
|
|
4
|
+
const Flex = styled.div`
|
|
5
|
+
display: flex;
|
|
6
|
+
justify-content: ${({ justifyContent }) => justifyContent};
|
|
7
|
+
flex-direction: ${({ flexDirection }) => flexDirection};
|
|
8
|
+
align-items: ${({ alignItems }) => alignItems};
|
|
9
|
+
flex-wrap: ${({ flexWrap }) => flexWrap};
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
Flex.defaultProps = {
|
|
13
|
+
justifyContent: 'normal',
|
|
14
|
+
flexDirection: 'row',
|
|
15
|
+
flexWrap: 'nowrap',
|
|
16
|
+
alignItems: 'normal',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
Flex.propTypes = {
|
|
20
|
+
flexDirection: PropTypes.string,
|
|
21
|
+
flexWrap: PropTypes.string,
|
|
22
|
+
justifyContent: PropTypes.string,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default Flex;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`<Flex /> should match snapshot 1`] = `
|
|
4
|
+
.c0 {
|
|
5
|
+
display: -webkit-box;
|
|
6
|
+
display: -webkit-flex;
|
|
7
|
+
display: -ms-flexbox;
|
|
8
|
+
display: flex;
|
|
9
|
+
-webkit-box-pack: normal;
|
|
10
|
+
-webkit-justify-content: normal;
|
|
11
|
+
-ms-flex-pack: normal;
|
|
12
|
+
justify-content: normal;
|
|
13
|
+
-webkit-flex-direction: row;
|
|
14
|
+
-ms-flex-direction: row;
|
|
15
|
+
flex-direction: row;
|
|
16
|
+
-webkit-align-items: normal;
|
|
17
|
+
-webkit-box-align: normal;
|
|
18
|
+
-ms-flex-align: normal;
|
|
19
|
+
align-items: normal;
|
|
20
|
+
-webkit-flex-wrap: nowrap;
|
|
21
|
+
-ms-flex-wrap: nowrap;
|
|
22
|
+
flex-wrap: nowrap;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
<div
|
|
26
|
+
className="c0"
|
|
27
|
+
/>
|
|
28
|
+
`;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import renderer from 'react-test-renderer';
|
|
3
|
+
import Flex from '../index';
|
|
4
|
+
|
|
5
|
+
describe('<Flex />', () => {
|
|
6
|
+
it('should match snapshot', () => {
|
|
7
|
+
const tree = renderer.create(<Flex />).toJSON();
|
|
8
|
+
|
|
9
|
+
expect(tree).toMatchSnapshot();
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* HeaderActions
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import PropTypes from 'prop-types';
|
|
9
|
+
import { HeaderActions as Wrapper } from '@punch-in/buffet-modern';
|
|
10
|
+
|
|
11
|
+
import Button from '../Button';
|
|
12
|
+
|
|
13
|
+
function HeaderActions({ actions }) {
|
|
14
|
+
return (
|
|
15
|
+
<Wrapper>
|
|
16
|
+
{actions.map((action, index) => {
|
|
17
|
+
const { Component, disabled, label, onClick } = action;
|
|
18
|
+
|
|
19
|
+
if (Component) {
|
|
20
|
+
return <Component {...action} key={action.key || index} />;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<Button
|
|
25
|
+
key={label}
|
|
26
|
+
onClick={onClick}
|
|
27
|
+
disabled={disabled || false}
|
|
28
|
+
{...action}
|
|
29
|
+
>
|
|
30
|
+
{label}
|
|
31
|
+
</Button>
|
|
32
|
+
);
|
|
33
|
+
})}
|
|
34
|
+
</Wrapper>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
HeaderActions.defaultProps = {
|
|
39
|
+
actions: [],
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
HeaderActions.propTypes = {
|
|
43
|
+
actions: PropTypes.arrayOf(
|
|
44
|
+
PropTypes.shape({
|
|
45
|
+
disabled: PropTypes.bool,
|
|
46
|
+
onClick: PropTypes.func,
|
|
47
|
+
title: PropTypes.string,
|
|
48
|
+
})
|
|
49
|
+
),
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default HeaderActions;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { mount } from 'enzyme';
|
|
3
|
+
|
|
4
|
+
import HeaderActions from '../index';
|
|
5
|
+
|
|
6
|
+
const defaultProps = {};
|
|
7
|
+
const renderComponent = (props = defaultProps) =>
|
|
8
|
+
mount(<HeaderActions {...props} />);
|
|
9
|
+
|
|
10
|
+
describe('<HeaderActions />', () => {
|
|
11
|
+
// eslint-disable-next-line jest/expect-expect
|
|
12
|
+
it('should not crash', () => {
|
|
13
|
+
renderComponent();
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* HeaderTitle
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import PropTypes from 'prop-types';
|
|
9
|
+
import { upperFirst } from 'lodash';
|
|
10
|
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
11
|
+
import { faPencilAlt } from '@fortawesome/free-solid-svg-icons';
|
|
12
|
+
|
|
13
|
+
import { HeaderTitle as Wrapper } from '@punch-in/buffet-modern';
|
|
14
|
+
|
|
15
|
+
function HeaderTitle({ title, children, cta }) {
|
|
16
|
+
const content = upperFirst(title) || children;
|
|
17
|
+
const renderCTA = () => {
|
|
18
|
+
if (cta) {
|
|
19
|
+
const { onClick } = cta;
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<FontAwesomeIcon
|
|
23
|
+
icon={faPencilAlt}
|
|
24
|
+
onClick={onClick}
|
|
25
|
+
role="button"
|
|
26
|
+
tabIndex="0"
|
|
27
|
+
size="sm"
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return null;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Wrapper>
|
|
37
|
+
<h1>
|
|
38
|
+
{content}
|
|
39
|
+
{renderCTA()}
|
|
40
|
+
</h1>
|
|
41
|
+
</Wrapper>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
HeaderTitle.defaultProps = {
|
|
46
|
+
children: null,
|
|
47
|
+
cta: null,
|
|
48
|
+
title: null,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
HeaderTitle.propTypes = {
|
|
52
|
+
children: PropTypes.node,
|
|
53
|
+
cta: PropTypes.shape({
|
|
54
|
+
onClick: PropTypes.func,
|
|
55
|
+
}),
|
|
56
|
+
title: PropTypes.string,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default HeaderTitle;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { mount } from 'enzyme';
|
|
3
|
+
|
|
4
|
+
import HeaderTitle from '../index';
|
|
5
|
+
|
|
6
|
+
const defaultProps = {};
|
|
7
|
+
const renderComponent = (props = defaultProps) =>
|
|
8
|
+
mount(<HeaderTitle {...props} />);
|
|
9
|
+
|
|
10
|
+
describe('<HeaderTitle />', () => {
|
|
11
|
+
// eslint-disable-next-line jest/expect-expect
|
|
12
|
+
it('should not crash', () => {
|
|
13
|
+
renderComponent();
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import {
|
|
4
|
+
faSearch,
|
|
5
|
+
faEye,
|
|
6
|
+
faAngleLeft,
|
|
7
|
+
faAngleRight,
|
|
8
|
+
faPencilAlt,
|
|
9
|
+
faSortDown,
|
|
10
|
+
faSortUp,
|
|
11
|
+
faTrashAlt,
|
|
12
|
+
faPlus,
|
|
13
|
+
} from '@fortawesome/free-solid-svg-icons';
|
|
14
|
+
import { faClock } from '@fortawesome/free-regular-svg-icons';
|
|
15
|
+
import { Icon as StyledIcon } from '@punch-in/buffet-modern';
|
|
16
|
+
|
|
17
|
+
const iconMap = new Map([
|
|
18
|
+
['time', faClock],
|
|
19
|
+
['password', faEye],
|
|
20
|
+
['search', faSearch],
|
|
21
|
+
['left', faAngleLeft],
|
|
22
|
+
['right', faAngleRight],
|
|
23
|
+
['pencil', faPencilAlt],
|
|
24
|
+
['asc', faSortUp],
|
|
25
|
+
['desc', faSortDown],
|
|
26
|
+
['trash', faTrashAlt],
|
|
27
|
+
['plus', faPlus],
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
function Icon({ icon, className }) {
|
|
31
|
+
if (iconMap.has(icon)) {
|
|
32
|
+
return (
|
|
33
|
+
<StyledIcon icon={iconMap.get(icon)} className={className || undefined} />
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return icon || null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
Icon.defaultProps = {
|
|
41
|
+
className: null,
|
|
42
|
+
icon: 'search',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
Icon.propTypes = {
|
|
46
|
+
className: PropTypes.string,
|
|
47
|
+
icon: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default Icon;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { mount } from 'enzyme';
|
|
3
|
+
// import renderer from 'react-test-renderer';
|
|
4
|
+
import Icon from '../index';
|
|
5
|
+
|
|
6
|
+
let renderedComponent;
|
|
7
|
+
const renderComponent = (props = {}) => mount(<Icon {...props} />);
|
|
8
|
+
|
|
9
|
+
describe('<Icon />', () => {
|
|
10
|
+
describe('<Icon /> attributes', () => {
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
renderedComponent.unmount();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should have a default icon equals to search', () => {
|
|
16
|
+
renderedComponent = renderComponent({ icon: 'search' });
|
|
17
|
+
const defaultType = 'search';
|
|
18
|
+
expect(renderedComponent.at(0).prop('icon')).toBe(defaultType);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
// NOTE: disabling this test
|
|
22
|
+
// describe('<Icon /> icon attributes', () => {
|
|
23
|
+
// it('should render the search icon', () => {
|
|
24
|
+
// const tree = renderer.create(<Icon icon="search" />).toJSON();
|
|
25
|
+
// expect(tree).toMatchSnapshot();
|
|
26
|
+
// });
|
|
27
|
+
|
|
28
|
+
// it('should render the password icon', () => {
|
|
29
|
+
// const tree = renderer.create(<Icon icon="password" />).toJSON();
|
|
30
|
+
// expect(tree).toMatchSnapshot();
|
|
31
|
+
// });
|
|
32
|
+
// });
|
|
33
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/* eslint-disable react/no-array-index-key */
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* IconLinks
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import PropTypes from 'prop-types';
|
|
10
|
+
|
|
11
|
+
import { Links as StyledLinks } from '@punch-in/buffet-modern';
|
|
12
|
+
import Icon from '../Icon';
|
|
13
|
+
|
|
14
|
+
function IconLinks({ links }) {
|
|
15
|
+
return (
|
|
16
|
+
<StyledLinks>
|
|
17
|
+
{links.map(({ icon, onClick }, index) => (
|
|
18
|
+
<button key={index} onClick={onClick} type="button">
|
|
19
|
+
<Icon className="link-icon" icon={icon} />
|
|
20
|
+
</button>
|
|
21
|
+
))}
|
|
22
|
+
</StyledLinks>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
IconLinks.defaultProps = {
|
|
27
|
+
links: [],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
IconLinks.propTypes = {
|
|
31
|
+
links: PropTypes.arrayOf(
|
|
32
|
+
PropTypes.shape({
|
|
33
|
+
icon: PropTypes.node,
|
|
34
|
+
onClick: PropTypes.func,
|
|
35
|
+
})
|
|
36
|
+
),
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default IconLinks;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { mount } from 'enzyme';
|
|
3
|
+
|
|
4
|
+
import IconLinks from '../index';
|
|
5
|
+
|
|
6
|
+
describe('<IconLinks />', () => {
|
|
7
|
+
// eslint-disable-next-line jest/expect-expect
|
|
8
|
+
it('Should not crash', () => {
|
|
9
|
+
mount(<IconLinks />);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('Should render some icons', () => {
|
|
13
|
+
const icons = [{ icon: 'trash', onClick: jest.fn() }];
|
|
14
|
+
const renderedComponent = mount(<IconLinks links={icons} />);
|
|
15
|
+
const buttons = renderedComponent.find('button');
|
|
16
|
+
|
|
17
|
+
buttons.at(0).simulate('click');
|
|
18
|
+
|
|
19
|
+
expect(icons[0].onClick).toHaveBeenCalled();
|
|
20
|
+
expect(
|
|
21
|
+
buttons
|
|
22
|
+
.at(0)
|
|
23
|
+
.find('svg')
|
|
24
|
+
.prop('className')
|
|
25
|
+
).toContain('trash');
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* InputNumber
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import RcInputNumber from 'rc-input-number';
|
|
9
|
+
import PropTypes from 'prop-types';
|
|
10
|
+
import { InputNumber as StyledInputNumber } from '@punch-in/buffet-modern';
|
|
11
|
+
|
|
12
|
+
function InputNumber({
|
|
13
|
+
autoFocus,
|
|
14
|
+
id,
|
|
15
|
+
className,
|
|
16
|
+
name,
|
|
17
|
+
onChange,
|
|
18
|
+
tabIndex,
|
|
19
|
+
value,
|
|
20
|
+
...rest
|
|
21
|
+
}) {
|
|
22
|
+
const handleChange = data => {
|
|
23
|
+
if (data !== null) {
|
|
24
|
+
const target = {
|
|
25
|
+
id,
|
|
26
|
+
name,
|
|
27
|
+
type: 'number',
|
|
28
|
+
value: data,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
onChange({ target });
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<StyledInputNumber className={className}>
|
|
37
|
+
<RcInputNumber
|
|
38
|
+
{...rest}
|
|
39
|
+
autoFocus={autoFocus}
|
|
40
|
+
id={id || name}
|
|
41
|
+
name={name}
|
|
42
|
+
onChange={handleChange}
|
|
43
|
+
tabIndex={tabIndex}
|
|
44
|
+
value={value}
|
|
45
|
+
className="inputNumber"
|
|
46
|
+
/>
|
|
47
|
+
</StyledInputNumber>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
InputNumber.defaultProps = {
|
|
52
|
+
autoComplete: 'off',
|
|
53
|
+
autoFocus: false,
|
|
54
|
+
className: null,
|
|
55
|
+
id: null,
|
|
56
|
+
onChange: () => {},
|
|
57
|
+
placeholder: null,
|
|
58
|
+
tabIndex: '0',
|
|
59
|
+
value: 0,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
InputNumber.propTypes = {
|
|
63
|
+
autoComplete: PropTypes.string,
|
|
64
|
+
autoFocus: PropTypes.bool,
|
|
65
|
+
className: PropTypes.string,
|
|
66
|
+
id: PropTypes.string,
|
|
67
|
+
name: PropTypes.string.isRequired,
|
|
68
|
+
onChange: PropTypes.func,
|
|
69
|
+
placeholder: PropTypes.string,
|
|
70
|
+
tabIndex: PropTypes.string,
|
|
71
|
+
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export default InputNumber;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { IconText, IconWrapper } from '@punch-in/buffet-modern';
|
|
4
|
+
|
|
5
|
+
import Icon from '../Icon';
|
|
6
|
+
|
|
7
|
+
function PrefixIcon({ type, icon }) {
|
|
8
|
+
if (icon) {
|
|
9
|
+
return (
|
|
10
|
+
<IconWrapper>
|
|
11
|
+
<Icon icon={icon} />
|
|
12
|
+
</IconWrapper>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
if (type === 'search') {
|
|
16
|
+
return (
|
|
17
|
+
<IconWrapper>
|
|
18
|
+
<Icon icon={type} />
|
|
19
|
+
</IconWrapper>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
if (type === 'email') {
|
|
23
|
+
return <IconText text="@" />;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
PrefixIcon.defaultProps = {
|
|
30
|
+
icon: null,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
PrefixIcon.propTypes = {
|
|
34
|
+
icon: PropTypes.node,
|
|
35
|
+
type: PropTypes.string.isRequired,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default PrefixIcon;
|