@transferwise/components 46.28.0 → 46.29.1
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/build/i18n/hu.json +1 -1
- package/build/index.js +141 -686
- package/build/index.js.map +1 -1
- package/build/index.mjs +144 -686
- package/build/index.mjs.map +1 -1
- package/build/main.css +16 -5
- package/build/styles/logo/Logo.css +16 -0
- package/build/styles/main.css +16 -5
- package/build/types/alert/Alert.d.ts.map +1 -1
- package/build/types/common/hooks/index.d.ts +0 -1
- package/build/types/dimmer/Dimmer.d.ts.map +1 -1
- package/build/types/flowNavigation/FlowNavigation.d.ts +3 -3
- package/build/types/flowNavigation/FlowNavigation.d.ts.map +1 -1
- package/build/types/index.d.ts +0 -1
- package/build/types/index.d.ts.map +1 -1
- package/build/types/inputs/SelectInput.d.ts.map +1 -1
- package/build/types/inputs/_BottomSheet.d.ts.map +1 -1
- package/build/types/inputs/_Popover.d.ts.map +1 -1
- package/build/types/loader/Loader.d.ts.map +1 -1
- package/build/types/logo/Logo.d.ts.map +1 -1
- package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
- package/build/types/popover/Popover.d.ts.map +1 -1
- package/build/types/segmentedControl/SegmentedControl.d.ts +2 -2
- package/build/types/segmentedControl/SegmentedControl.d.ts.map +1 -1
- package/build/types/select/Select.d.ts.map +1 -1
- package/build/types/stepper/deviceDetection.d.ts.map +1 -1
- package/build/types/uploadInput/uploadButton/UploadButton.d.ts.map +1 -1
- package/package.json +10 -8
- package/src/accordion/Accordion.story.tsx +1 -1
- package/src/alert/Alert.tsx +2 -1
- package/src/avatar/colors/colors.ts +1 -1
- package/src/body/Body.spec.tsx +1 -1
- package/src/body/Body.story.tsx +8 -8
- package/src/checkbox/Checkbox.js +1 -1
- package/src/checkboxButton/CheckboxButton.spec.tsx +0 -1
- package/src/common/Option/Option.tsx +1 -1
- package/src/common/deviceDetection/deviceDetection.js +1 -1
- package/src/common/deviceDetection/deviceDetection.spec.js +4 -2
- package/src/common/hooks/index.js +0 -1
- package/src/common/responsivePanel/ResponsivePanel.spec.js +11 -15
- package/src/decision/Decision.spec.js +0 -2
- package/src/dimmer/Dimmer.tsx +6 -2
- package/src/flowNavigation/FlowNavigation.spec.js +7 -22
- package/src/flowNavigation/FlowNavigation.tsx +20 -33
- package/src/flowNavigation/__snapshots__/FlowNavigation.spec.js.snap +2 -2
- package/src/i18n/hu.json +1 -1
- package/src/index.ts +0 -1
- package/src/inlineAlert/InlineAlert.story.tsx +8 -7
- package/src/inputs/SelectInput.tsx +1 -0
- package/src/inputs/_BottomSheet.tsx +33 -28
- package/src/inputs/_Popover.tsx +23 -20
- package/src/link/Link.story.tsx +16 -16
- package/src/loader/Loader.tsx +0 -1
- package/src/logo/Logo.css +16 -0
- package/src/logo/Logo.js +4 -9
- package/src/logo/Logo.less +16 -0
- package/src/logo/__snapshots__/Logo.spec.js.snap +104 -8
- package/src/main.css +16 -5
- package/src/main.less +0 -1
- package/src/moneyInput/MoneyInput.story.tsx +3 -3
- package/src/nudge/Nudge.spec.tsx +5 -5
- package/src/phoneNumberInput/PhoneNumberInput.tsx +2 -1
- package/src/phoneNumberInput/utils/cleanNumber/cleanNumber.ts +1 -1
- package/src/popover/Popover.tsx +2 -1
- package/src/promoCard/PromoCard.tsx +1 -1
- package/src/provider/theme/ThemeProvider.story.tsx +21 -0
- package/src/radioGroup/RadioGroup.spec.js +1 -1
- package/src/section/Section.story.tsx +2 -1
- package/src/segmentedControl/SegmentedControl.spec.tsx +88 -2
- package/src/segmentedControl/SegmentedControl.story.tsx +54 -16
- package/src/segmentedControl/SegmentedControl.tsx +21 -33
- package/src/select/Select.js +2 -3
- package/src/stepper/deviceDetection.js +1 -2
- package/src/stepper/deviceDetection.spec.js +8 -3
- package/src/test-utils/index.js +1 -1
- package/src/test-utils/story-config.ts +1 -1
- package/src/title/Title.spec.tsx +1 -1
- package/src/typeahead/Typeahead.spec.js +4 -2
- package/src/upload/Upload.spec.js +8 -4
- package/src/uploadInput/uploadButton/UploadButton.tsx +1 -0
- package/build/styles/dynamicFieldDefinitionList/FormattedValue/FormattedValue.css +0 -5
- package/build/types/common/hooks/useClientWidth/useClientWidth.d.ts +0 -11
- package/build/types/common/hooks/useClientWidth/useClientWidth.d.ts.map +0 -1
- package/build/types/common/requirements.d.ts +0 -3
- package/build/types/common/requirements.d.ts.map +0 -1
- package/build/types/dynamicFieldDefinitionList/DynamicFieldDefinitionList.d.ts +0 -21
- package/build/types/dynamicFieldDefinitionList/DynamicFieldDefinitionList.d.ts.map +0 -1
- package/build/types/dynamicFieldDefinitionList/FormattedValue/FormattedValue.d.ts +0 -12
- package/build/types/dynamicFieldDefinitionList/FormattedValue/FormattedValue.d.ts.map +0 -1
- package/build/types/dynamicFieldDefinitionList/FormattedValue/index.d.ts +0 -2
- package/build/types/dynamicFieldDefinitionList/FormattedValue/index.d.ts.map +0 -1
- package/build/types/dynamicFieldDefinitionList/index.d.ts +0 -2
- package/build/types/dynamicFieldDefinitionList/index.d.ts.map +0 -1
- package/build/types/dynamicFieldDefinitionList/utils/createDefinitions.d.ts +0 -2
- package/build/types/dynamicFieldDefinitionList/utils/createDefinitions.d.ts.map +0 -1
- package/build/types/dynamicFieldDefinitionList/utils/text-format.d.ts +0 -2
- package/build/types/dynamicFieldDefinitionList/utils/text-format.d.ts.map +0 -1
- package/src/common/hooks/useClientWidth/useClientWidth.spec.js +0 -77
- package/src/common/hooks/useClientWidth/useClientWidth.tsx +0 -47
- package/src/dynamicFieldDefinitionList/DynamicFieldDefinitionList.js +0 -41
- package/src/dynamicFieldDefinitionList/DynamicFieldDefinitionList.spec.js +0 -21
- package/src/dynamicFieldDefinitionList/DynamicFieldDefinitionList.story.js +0 -134
- package/src/dynamicFieldDefinitionList/FormattedValue/FormattedValue.css +0 -5
- package/src/dynamicFieldDefinitionList/FormattedValue/FormattedValue.js +0 -73
- package/src/dynamicFieldDefinitionList/FormattedValue/FormattedValue.less +0 -4
- package/src/dynamicFieldDefinitionList/FormattedValue/FormattedValue.spec.js +0 -200
- package/src/dynamicFieldDefinitionList/FormattedValue/index.js +0 -1
- package/src/dynamicFieldDefinitionList/index.js +0 -1
- package/src/dynamicFieldDefinitionList/utils/createDefinitions.js +0 -33
- package/src/dynamicFieldDefinitionList/utils/createDefinitions.spec.js +0 -83
- package/src/dynamicFieldDefinitionList/utils/text-format.js +0 -46
- package/src/dynamicFieldDefinitionList/utils/text-format.spec.js +0 -43
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { select, text, number, date } from '@storybook/addon-knobs';
|
|
2
|
-
|
|
3
|
-
import { Layout } from '../common';
|
|
4
|
-
|
|
5
|
-
import DynamicFieldDefinitionList from './DynamicFieldDefinitionList';
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
component: DynamicFieldDefinitionList,
|
|
9
|
-
title: 'Other/DynamicFieldDefinitionList',
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export const Basic = () => {
|
|
13
|
-
const textDF = text('textDF', 'helloworld');
|
|
14
|
-
const numberDF = number('numberDF', 123456);
|
|
15
|
-
const dateDF = date('dateDF', new Date('01-01-2000'));
|
|
16
|
-
const passwordDF = text('passwordDF', 'password');
|
|
17
|
-
const phoneDF = text('phoneDF', '+441234567890');
|
|
18
|
-
const textareaDF = text('textareaDF', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit');
|
|
19
|
-
const selectDF = select('selectDF', ['1', '2'], '1');
|
|
20
|
-
const radioDF = select('radioDF', ['1', '2'], '1');
|
|
21
|
-
|
|
22
|
-
return (
|
|
23
|
-
<DynamicFieldDefinitionList
|
|
24
|
-
title="title"
|
|
25
|
-
layout={Layout.VERTICAL_TWO_COLUMN}
|
|
26
|
-
model={{
|
|
27
|
-
text: textDF,
|
|
28
|
-
number: numberDF,
|
|
29
|
-
select: selectDF,
|
|
30
|
-
date: new Date(dateDF),
|
|
31
|
-
checkbox: true,
|
|
32
|
-
radio: radioDF,
|
|
33
|
-
password: passwordDF,
|
|
34
|
-
telephone: phoneDF,
|
|
35
|
-
textarea: textareaDF,
|
|
36
|
-
}}
|
|
37
|
-
fields={{
|
|
38
|
-
text: {
|
|
39
|
-
title: 'Text',
|
|
40
|
-
type: 'text',
|
|
41
|
-
displayFormat: '***** - *****||*-*-*',
|
|
42
|
-
width: 'md',
|
|
43
|
-
refreshRequirementsOnChange: true,
|
|
44
|
-
tagClassName: {
|
|
45
|
-
h3: true,
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
number: {
|
|
49
|
-
title: 'Number',
|
|
50
|
-
type: 'number',
|
|
51
|
-
width: 'md',
|
|
52
|
-
refreshRequirementsOnChange: true,
|
|
53
|
-
},
|
|
54
|
-
select: {
|
|
55
|
-
title: 'Select',
|
|
56
|
-
type: 'string',
|
|
57
|
-
control: 'select',
|
|
58
|
-
width: 'md',
|
|
59
|
-
refreshRequirementsOnChange: true,
|
|
60
|
-
values: [
|
|
61
|
-
{
|
|
62
|
-
key: '1',
|
|
63
|
-
name: 'One',
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
key: '2',
|
|
67
|
-
name: 'Two',
|
|
68
|
-
},
|
|
69
|
-
],
|
|
70
|
-
},
|
|
71
|
-
password: {
|
|
72
|
-
title: 'Password',
|
|
73
|
-
type: 'string',
|
|
74
|
-
control: 'password',
|
|
75
|
-
width: 'md',
|
|
76
|
-
refreshRequirementsOnChange: true,
|
|
77
|
-
},
|
|
78
|
-
date: {
|
|
79
|
-
title: 'Date',
|
|
80
|
-
type: 'string',
|
|
81
|
-
format: 'date',
|
|
82
|
-
refreshRequirementsOnChange: true,
|
|
83
|
-
},
|
|
84
|
-
telephone: {
|
|
85
|
-
title: 'Telephone',
|
|
86
|
-
type: 'string',
|
|
87
|
-
control: 'tel',
|
|
88
|
-
placeholder: 'Enter...',
|
|
89
|
-
},
|
|
90
|
-
radio: {
|
|
91
|
-
title: 'Radio',
|
|
92
|
-
type: 'string',
|
|
93
|
-
control: 'radio',
|
|
94
|
-
width: 'md',
|
|
95
|
-
refreshRequirementsOnChange: true,
|
|
96
|
-
values: [
|
|
97
|
-
{
|
|
98
|
-
key: '1',
|
|
99
|
-
name: 'One',
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
key: '2',
|
|
103
|
-
name: 'Two',
|
|
104
|
-
},
|
|
105
|
-
],
|
|
106
|
-
},
|
|
107
|
-
checkbox: {
|
|
108
|
-
title: 'Checkbox',
|
|
109
|
-
type: 'boolean',
|
|
110
|
-
placeholder: 'Label',
|
|
111
|
-
width: 'md',
|
|
112
|
-
refreshRequirementsOnChange: true,
|
|
113
|
-
},
|
|
114
|
-
textarea: {
|
|
115
|
-
title: 'Textarea',
|
|
116
|
-
type: 'string',
|
|
117
|
-
control: 'textarea',
|
|
118
|
-
refreshRequirementsOnChange: true,
|
|
119
|
-
},
|
|
120
|
-
file: {
|
|
121
|
-
title: 'File',
|
|
122
|
-
type: 'string',
|
|
123
|
-
format: 'base64url',
|
|
124
|
-
refreshRequirementsOnChange: true,
|
|
125
|
-
},
|
|
126
|
-
hidden: {
|
|
127
|
-
type: 'string',
|
|
128
|
-
hidden: true,
|
|
129
|
-
default: 'hidden-value',
|
|
130
|
-
},
|
|
131
|
-
}}
|
|
132
|
-
/>
|
|
133
|
-
);
|
|
134
|
-
};
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { formatDate, formatNumber } from '@transferwise/formatting';
|
|
2
|
-
import classNames from 'classnames';
|
|
3
|
-
import PropTypes from 'prop-types';
|
|
4
|
-
import { useIntl } from 'react-intl';
|
|
5
|
-
|
|
6
|
-
import { formatUsingPattern } from '../utils/text-format';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
*
|
|
10
|
-
* @param {Array} options
|
|
11
|
-
* @param {string|number} value
|
|
12
|
-
*/
|
|
13
|
-
const getValueLabel = (options, value) => {
|
|
14
|
-
const option = options.find((currentOption) => currentOption.value === value);
|
|
15
|
-
return option && option.label ? option.label : value;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
*
|
|
20
|
-
* @param {string} value
|
|
21
|
-
*/
|
|
22
|
-
const mask = (value) => new Array(value.length + 1).join('*');
|
|
23
|
-
|
|
24
|
-
const FormattedValue = ({ field, value }) => {
|
|
25
|
-
const { locale } = useIntl();
|
|
26
|
-
const style = [];
|
|
27
|
-
if (field.tagClassName && field.tagClassName.h3) {
|
|
28
|
-
style.push('np-text-body-large-bold');
|
|
29
|
-
style.push('formatted-value__h3-custom-alignment');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
switch (field.control) {
|
|
33
|
-
case 'select':
|
|
34
|
-
case 'radio':
|
|
35
|
-
return <span>{getValueLabel(field.values, value)}</span>;
|
|
36
|
-
case 'date':
|
|
37
|
-
return <span>{formatDate(value instanceof Date ? value : new Date(value), locale)}</span>;
|
|
38
|
-
case 'number':
|
|
39
|
-
return <span>{formatNumber(value, locale)}</span>;
|
|
40
|
-
case 'password':
|
|
41
|
-
return <span>{mask(value)}</span>;
|
|
42
|
-
case 'file':
|
|
43
|
-
return (
|
|
44
|
-
<div className="thumbnail">
|
|
45
|
-
<img alt={field.title} src={value} />
|
|
46
|
-
</div>
|
|
47
|
-
);
|
|
48
|
-
case 'checkbox':
|
|
49
|
-
return <span>{JSON.stringify(value)}</span>;
|
|
50
|
-
default:
|
|
51
|
-
return (
|
|
52
|
-
<span className={classNames(style)}>{formatUsingPattern(value, field.displayFormat)}</span>
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
FormattedValue.propTypes = {
|
|
58
|
-
field: PropTypes.shape({
|
|
59
|
-
control: PropTypes.string.isRequired,
|
|
60
|
-
displayFormat: PropTypes.string,
|
|
61
|
-
refreshRequirementsOnChange: PropTypes.bool,
|
|
62
|
-
title: PropTypes.string.isRequired,
|
|
63
|
-
type: PropTypes.string.isRequired,
|
|
64
|
-
width: PropTypes.string,
|
|
65
|
-
tagClassName: PropTypes.shape({
|
|
66
|
-
h3: PropTypes.bool,
|
|
67
|
-
}),
|
|
68
|
-
values: PropTypes.arrayOf(PropTypes.shape({ value: PropTypes.any })),
|
|
69
|
-
}).isRequired,
|
|
70
|
-
value: PropTypes.any.isRequired,
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
export default FormattedValue;
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
import { formatNumber } from '@transferwise/formatting';
|
|
2
|
-
import { shallow } from 'enzyme';
|
|
3
|
-
import { useIntl } from 'react-intl';
|
|
4
|
-
|
|
5
|
-
import FormattedValue from './FormattedValue';
|
|
6
|
-
|
|
7
|
-
jest.mock('react-intl');
|
|
8
|
-
|
|
9
|
-
describe('FormattedValue', () => {
|
|
10
|
-
let props;
|
|
11
|
-
let value;
|
|
12
|
-
let component;
|
|
13
|
-
let item;
|
|
14
|
-
useIntl.mockReturnValue({ locale: 'en-GB' });
|
|
15
|
-
|
|
16
|
-
describe('when given a text field', () => {
|
|
17
|
-
beforeEach(() => {
|
|
18
|
-
props = {
|
|
19
|
-
value: 'ABCD',
|
|
20
|
-
field: {
|
|
21
|
-
control: 'text',
|
|
22
|
-
displayFormat: '** - **',
|
|
23
|
-
refreshRequirementsOnChange: true,
|
|
24
|
-
title: 'Text',
|
|
25
|
-
type: 'string',
|
|
26
|
-
width: 'md',
|
|
27
|
-
tagClassName: {
|
|
28
|
-
h3: true,
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
component = shallow(<FormattedValue {...props} />);
|
|
33
|
-
item = component.find('span');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('should display the formatted text value', () => {
|
|
37
|
-
expect(item.text()).toBe('AB - CD');
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('has h3 styling added when provided', () => {
|
|
41
|
-
expect(item.find('.np-text-body-large-bold')).toHaveLength(1);
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
describe('when given a number field', () => {
|
|
46
|
-
beforeEach(() => {
|
|
47
|
-
value = 1234;
|
|
48
|
-
props = {
|
|
49
|
-
value,
|
|
50
|
-
field: {
|
|
51
|
-
title: 'Number',
|
|
52
|
-
type: 'number',
|
|
53
|
-
width: 'md',
|
|
54
|
-
refreshRequirementsOnChange: true,
|
|
55
|
-
control: 'number',
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
component = shallow(<FormattedValue {...props} />);
|
|
59
|
-
item = component.find('span');
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('should display the formatted number value', () => {
|
|
63
|
-
expect(item.text()).toBe(formatNumber(value));
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
describe('when given a date field', () => {
|
|
68
|
-
beforeEach(() => {
|
|
69
|
-
props = {
|
|
70
|
-
value: '2000-12-20T00:00:00.000Z',
|
|
71
|
-
field: {
|
|
72
|
-
title: 'Date label',
|
|
73
|
-
type: 'date',
|
|
74
|
-
control: 'date',
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
component = shallow(<FormattedValue {...props} />);
|
|
78
|
-
item = component.find('span');
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it('should display the formatted date value', () => {
|
|
82
|
-
expect(item.text()).toBe('20/12/2000');
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
describe('when given a select field', () => {
|
|
87
|
-
beforeEach(() => {
|
|
88
|
-
props = {
|
|
89
|
-
value: '2',
|
|
90
|
-
field: {
|
|
91
|
-
title: 'Select label',
|
|
92
|
-
type: 'select',
|
|
93
|
-
control: 'select',
|
|
94
|
-
values: [
|
|
95
|
-
{
|
|
96
|
-
value: '1',
|
|
97
|
-
label: 'One',
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
value: '2',
|
|
101
|
-
label: 'Two',
|
|
102
|
-
},
|
|
103
|
-
],
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
component = shallow(<FormattedValue {...props} />);
|
|
107
|
-
item = component.find('span');
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('should display the selected option value', () => {
|
|
111
|
-
expect(item.text()).toBe('Two');
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
describe('when given a radio field', () => {
|
|
116
|
-
beforeEach(() => {
|
|
117
|
-
props = {
|
|
118
|
-
value: '2',
|
|
119
|
-
field: {
|
|
120
|
-
title: 'Radio label',
|
|
121
|
-
type: 'radio',
|
|
122
|
-
control: 'select',
|
|
123
|
-
values: [
|
|
124
|
-
{
|
|
125
|
-
value: '1',
|
|
126
|
-
label: 'One',
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
value: '2',
|
|
130
|
-
label: 'Two',
|
|
131
|
-
},
|
|
132
|
-
],
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
component = shallow(<FormattedValue {...props} />);
|
|
136
|
-
item = component.find('span');
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('should display the selected radio value', () => {
|
|
140
|
-
expect(item.text()).toBe('Two');
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
describe('when given a checkbox field', () => {
|
|
145
|
-
beforeEach(() => {
|
|
146
|
-
props = {
|
|
147
|
-
value: true,
|
|
148
|
-
field: {
|
|
149
|
-
title: 'Checkbox label',
|
|
150
|
-
type: 'boolean',
|
|
151
|
-
control: 'checkbox',
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
component = shallow(<FormattedValue {...props} />);
|
|
155
|
-
item = component.find('span');
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it('should display the boolean', () => {
|
|
159
|
-
expect(item.text()).toBe('true');
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
describe('when given a password field', () => {
|
|
164
|
-
beforeEach(() => {
|
|
165
|
-
props = {
|
|
166
|
-
value: 'qwe123',
|
|
167
|
-
field: {
|
|
168
|
-
title: 'Password label',
|
|
169
|
-
type: 'string',
|
|
170
|
-
control: 'password',
|
|
171
|
-
},
|
|
172
|
-
};
|
|
173
|
-
component = shallow(<FormattedValue {...props} />);
|
|
174
|
-
item = component.find('span');
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it('should display the password masked', () => {
|
|
178
|
-
expect(item.text()).toBe('******');
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
describe('when given a file', () => {
|
|
183
|
-
beforeEach(() => {
|
|
184
|
-
props = {
|
|
185
|
-
value: 'qwe123',
|
|
186
|
-
field: {
|
|
187
|
-
title: 'A File',
|
|
188
|
-
type: 'file',
|
|
189
|
-
control: 'file',
|
|
190
|
-
},
|
|
191
|
-
};
|
|
192
|
-
component = shallow(<FormattedValue {...props} />);
|
|
193
|
-
item = component.find('img');
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
it('should display the value as source', () => {
|
|
197
|
-
expect(item.prop('src')).toBe('qwe123');
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './FormattedValue';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './DynamicFieldDefinitionList';
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import toPairs from 'lodash.topairs';
|
|
2
|
-
|
|
3
|
-
import FormattedValue from '../FormattedValue';
|
|
4
|
-
|
|
5
|
-
export default function createDefinitions(fields, model) {
|
|
6
|
-
return toPairs(fields)
|
|
7
|
-
.map(([name, field]) => createDefinition(name, field, model))
|
|
8
|
-
.filter((definition) => !!definition);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function createDefinition(name, field, model) {
|
|
12
|
-
const { title, group, hidden } = field;
|
|
13
|
-
|
|
14
|
-
if (!model[name] || hidden) {
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
title,
|
|
20
|
-
value: group ? (
|
|
21
|
-
group.map((groupField, groupFieldIndex) => (
|
|
22
|
-
<FormattedValue
|
|
23
|
-
key={groupFieldIndex} // eslint-disable-line react/no-array-index-key
|
|
24
|
-
field={groupField}
|
|
25
|
-
value={model[name]}
|
|
26
|
-
/>
|
|
27
|
-
))
|
|
28
|
-
) : (
|
|
29
|
-
<FormattedValue field={field} value={model[name]} />
|
|
30
|
-
),
|
|
31
|
-
key: name,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import createDefinitions from './createDefinitions';
|
|
2
|
-
|
|
3
|
-
const FIELD = { title: 'First', control: 'control', type: 'type' };
|
|
4
|
-
|
|
5
|
-
describe('createDefinitions', () => {
|
|
6
|
-
it('creates definitions with titles', () => {
|
|
7
|
-
const fields = {
|
|
8
|
-
first: { ...FIELD, title: 'First' },
|
|
9
|
-
second: { ...FIELD, title: 'Second' },
|
|
10
|
-
};
|
|
11
|
-
const model = { first: 'first value', second: 'second value' };
|
|
12
|
-
|
|
13
|
-
const definitions = createDefinitions(fields, model);
|
|
14
|
-
|
|
15
|
-
const titles = definitions.map(({ title }) => title);
|
|
16
|
-
expect(titles).toStrictEqual(['First', 'Second']);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('creates definitions with non-group and group values', () => {
|
|
20
|
-
const FIRST_SOLO = { ...FIELD, title: 'Solo title' };
|
|
21
|
-
const FIRST_GROUP = { ...FIELD, title: 'First group title' };
|
|
22
|
-
const SECOND_GROUP = { ...FIELD, title: 'Second group title' };
|
|
23
|
-
|
|
24
|
-
const fields = {
|
|
25
|
-
first: FIRST_SOLO,
|
|
26
|
-
second: {
|
|
27
|
-
group: [FIRST_GROUP, SECOND_GROUP],
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const model = {
|
|
32
|
-
first: 'first value',
|
|
33
|
-
second: 'second value',
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const definitions = createDefinitions(fields, model);
|
|
37
|
-
|
|
38
|
-
const values = definitions.map(({ value }) => value);
|
|
39
|
-
|
|
40
|
-
expect(values).toHaveLength(2);
|
|
41
|
-
|
|
42
|
-
const [first, [groupFirst, groupSecond]] = values;
|
|
43
|
-
|
|
44
|
-
expect(first.props.field).toStrictEqual(FIRST_SOLO);
|
|
45
|
-
expect(first.props.value).toBe('first value');
|
|
46
|
-
|
|
47
|
-
expect(groupFirst.props.field).toStrictEqual(FIRST_GROUP);
|
|
48
|
-
expect(groupFirst.props.value).toBe('second value');
|
|
49
|
-
|
|
50
|
-
expect(groupSecond.props.field).toStrictEqual(SECOND_GROUP);
|
|
51
|
-
expect(groupSecond.props.value).toBe('second value');
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('creates definitions with keys from names', () => {
|
|
55
|
-
const fields = {
|
|
56
|
-
first: { ...FIELD, title: 'First' },
|
|
57
|
-
second: { ...FIELD, title: 'Second' },
|
|
58
|
-
};
|
|
59
|
-
const model = { first: 'first value', second: 'second value' };
|
|
60
|
-
|
|
61
|
-
const definitions = createDefinitions(fields, model);
|
|
62
|
-
|
|
63
|
-
const keys = definitions.map(({ key }) => key);
|
|
64
|
-
expect(keys).toStrictEqual(['first', 'second']);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('creates definitions without fields hidden or missing from model', () => {
|
|
68
|
-
const fields = {
|
|
69
|
-
hidden: { ...FIELD, title: 'Hidden', hidden: true },
|
|
70
|
-
present: { ...FIELD, title: 'Present' },
|
|
71
|
-
missing: { ...FIELD, title: 'Missing' },
|
|
72
|
-
};
|
|
73
|
-
const model = {
|
|
74
|
-
hidden: 'hidden value',
|
|
75
|
-
present: 'present value',
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const definitions = createDefinitions(fields, model);
|
|
79
|
-
|
|
80
|
-
expect(definitions).toHaveLength(1);
|
|
81
|
-
expect(definitions[0].key).toBe('present');
|
|
82
|
-
});
|
|
83
|
-
});
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
const formatUsingPattern = (value = '', pattern) => {
|
|
2
|
-
if (typeof pattern !== 'string') {
|
|
3
|
-
return value;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
let newPattern = pattern;
|
|
7
|
-
|
|
8
|
-
if (newPattern.indexOf('||') > 0) {
|
|
9
|
-
newPattern = newPattern.slice(0, Math.max(0, pattern.indexOf('||')));
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
let newValue = '';
|
|
13
|
-
let separators = 0;
|
|
14
|
-
let charactersToAllocate = value.length;
|
|
15
|
-
let position = 0;
|
|
16
|
-
|
|
17
|
-
while (charactersToAllocate) {
|
|
18
|
-
if (positionIsSeparator(newPattern, position)) {
|
|
19
|
-
newValue += newPattern[position];
|
|
20
|
-
separators += 1;
|
|
21
|
-
} else {
|
|
22
|
-
newValue += value[position - separators];
|
|
23
|
-
charactersToAllocate -= 1;
|
|
24
|
-
}
|
|
25
|
-
position += 1;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const separatorsAfterCursor = countSeparatorsAfterCursor(newPattern, position);
|
|
29
|
-
if (separatorsAfterCursor) {
|
|
30
|
-
newValue += newPattern.slice(position, separatorsAfterCursor);
|
|
31
|
-
}
|
|
32
|
-
return newValue;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const countSeparatorsAfterCursor = (newPattern, position) => {
|
|
36
|
-
let separators = 0;
|
|
37
|
-
while (positionIsSeparator(newPattern, position + separators)) {
|
|
38
|
-
separators += 1;
|
|
39
|
-
}
|
|
40
|
-
return separators;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const positionIsSeparator = (newPattern, position) =>
|
|
44
|
-
newPattern[position] && newPattern[position] !== '*';
|
|
45
|
-
|
|
46
|
-
export { formatUsingPattern };
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { formatUsingPattern } from './text-format';
|
|
2
|
-
|
|
3
|
-
describe('TextFormat,', () => {
|
|
4
|
-
let pattern;
|
|
5
|
-
let value;
|
|
6
|
-
|
|
7
|
-
describe('Given there is a pattern', () => {
|
|
8
|
-
describe('for numeric string', () => {
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
pattern = '** - ** - **';
|
|
11
|
-
value = '123456';
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('should format the value', () => {
|
|
15
|
-
expect(formatUsingPattern(value, pattern)).toBe('12 - 34 - 56');
|
|
16
|
-
});
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
describe('Given there are multiple patterns', () => {
|
|
21
|
-
describe('for string', () => {
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
pattern = '** - **||**-**-**';
|
|
24
|
-
value = 'ABCDEF';
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('should use the first option', () => {
|
|
28
|
-
expect(formatUsingPattern(value, pattern)).toBe('AB - CDEF');
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
describe('When no pattern supplied', () => {
|
|
34
|
-
beforeEach(() => {
|
|
35
|
-
pattern = '';
|
|
36
|
-
value = '123456';
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('should leave the value unaltered', () => {
|
|
40
|
-
expect(formatUsingPattern(value, pattern)).toBe('123456');
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
});
|