@axinom/mosaic-ui 0.31.0-rc.9 → 0.32.0-rc.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/dist/components/DynamicDataList/DynamicListDataEntry/Renderers/createInputRenderer/createInputRenderer.d.ts.map +1 -1
- package/dist/components/DynamicDataList/DynamicListDataEntry/Renderers/renderers.model.d.ts +5 -4
- package/dist/components/DynamicDataList/DynamicListDataEntry/Renderers/renderers.model.d.ts.map +1 -1
- package/dist/components/DynamicDataList/index.d.ts +1 -1
- package/dist/components/DynamicDataList/index.d.ts.map +1 -1
- package/dist/components/EmptyStation/EmptyStation.d.ts +1 -1
- package/dist/components/EmptyStation/EmptyStation.d.ts.map +1 -1
- package/dist/components/Explorer/Explorer.d.ts.map +1 -1
- package/dist/components/FormElements/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/components/FormElements/CustomTags/CustomTags.d.ts.map +1 -1
- package/dist/components/FormElements/DateTimeField/DateTimeText.d.ts.map +1 -1
- package/dist/components/FormElements/DateTimeField/DateTimeTextField.d.ts.map +1 -1
- package/dist/components/FormElements/Form.models.d.ts +4 -4
- package/dist/components/FormElements/Form.models.d.ts.map +1 -1
- package/dist/components/FormElements/FormElementContainer/FormElementContainer.d.ts.map +1 -1
- package/dist/components/FormElements/MaskedSingleLineText/MaskedSingleLineText.d.ts +20 -0
- package/dist/components/FormElements/MaskedSingleLineText/MaskedSingleLineText.d.ts.map +1 -0
- package/dist/components/FormElements/MaskedSingleLineText/MaskedSingleLineTextField.d.ts +15 -0
- package/dist/components/FormElements/MaskedSingleLineText/MaskedSingleLineTextField.d.ts.map +1 -0
- package/dist/components/FormElements/Radio/Radio.d.ts +1 -0
- package/dist/components/FormElements/Radio/Radio.d.ts.map +1 -1
- package/dist/components/FormElements/SingleLineText/SingleLineText.d.ts +5 -2
- package/dist/components/FormElements/SingleLineText/SingleLineText.d.ts.map +1 -1
- package/dist/components/FormElements/ToggleButton/ToggleButton.d.ts.map +1 -1
- package/dist/components/FormElements/index.d.ts +1 -0
- package/dist/components/FormElements/index.d.ts.map +1 -1
- package/dist/components/FormStation/FormStation.d.ts.map +1 -1
- package/dist/components/PageHeader/PageHeaderAction/PageHeaderAction.d.ts.map +1 -1
- package/dist/components/Utils/Postgraphile/index.d.ts +3 -3
- package/dist/components/Utils/Postgraphile/index.d.ts.map +1 -1
- package/dist/components/Utils/Transformers/Timestamp.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/helpers/utils.d.ts +8 -0
- package/dist/helpers/utils.d.ts.map +1 -1
- package/dist/index.es.js +4 -3
- package/dist/index.es.js.map +1 -0
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -0
- package/package.json +4 -3
- package/src/components/Actions/Action/Action.spec.tsx +2 -2
- package/src/components/Actions/Action/Action.tsx +1 -1
- package/src/components/DynamicDataList/DynamicListDataEntry/DynamicListDataEntry.scss +5 -1
- package/src/components/DynamicDataList/DynamicListDataEntry/Renderers/createInputRenderer/createInputRenderer.scss +0 -45
- package/src/components/DynamicDataList/DynamicListDataEntry/Renderers/createInputRenderer/createInputRenderer.spec.tsx +3 -61
- package/src/components/DynamicDataList/DynamicListDataEntry/Renderers/createInputRenderer/createInputRenderer.tsx +14 -15
- package/src/components/DynamicDataList/DynamicListDataEntry/Renderers/createSelectRenderer/createSelectRenderer.scss +2 -2
- package/src/components/DynamicDataList/DynamicListDataEntry/Renderers/renderers.model.ts +6 -4
- package/src/components/DynamicDataList/index.ts +2 -2
- package/src/components/EmptyStation/EmptyStation.spec.tsx +1 -1
- package/src/components/EmptyStation/EmptyStation.tsx +1 -1
- package/src/components/Explorer/Explorer.tsx +2 -2
- package/src/components/FormElements/Checkbox/Checkbox.scss +4 -1
- package/src/components/FormElements/Checkbox/Checkbox.tsx +1 -1
- package/src/components/FormElements/CustomTags/CustomTags.scss +0 -2
- package/src/components/FormElements/CustomTags/CustomTags.tsx +10 -4
- package/src/components/FormElements/DateTimeField/DateTimeText.tsx +1 -0
- package/src/components/FormElements/DateTimeField/DateTimeTextField.tsx +1 -2
- package/src/components/FormElements/Form.models.ts +4 -4
- package/src/components/FormElements/FormElementContainer/FormElementContainer.scss +6 -1
- package/src/components/FormElements/FormElementContainer/FormElementContainer.tsx +8 -1
- package/src/components/FormElements/MaskedSingleLineText/MaskedSingleLineText.spec.tsx +19 -0
- package/src/components/FormElements/MaskedSingleLineText/MaskedSingleLineText.stories.tsx +65 -0
- package/src/components/FormElements/MaskedSingleLineText/MaskedSingleLineText.tsx +60 -0
- package/src/components/FormElements/MaskedSingleLineText/MaskedSingleLineTextField.tsx +37 -0
- package/src/components/FormElements/Radio/Radio.scss +4 -0
- package/src/components/FormElements/Radio/Radio.spec.tsx +1 -1
- package/src/components/FormElements/Radio/Radio.tsx +30 -24
- package/src/components/FormElements/Select/Select.scss +10 -3
- package/src/components/FormElements/SingleLineText/SingleLineText.scss +1 -0
- package/src/components/FormElements/SingleLineText/SingleLineText.spec.tsx +2 -32
- package/src/components/FormElements/SingleLineText/SingleLineText.stories.tsx +9 -1
- package/src/components/FormElements/SingleLineText/SingleLineText.tsx +24 -32
- package/src/components/FormElements/Tags/Tags.scss +8 -1
- package/src/components/FormElements/ToggleButton/ToggleButton.scss +3 -2
- package/src/components/FormElements/ToggleButton/ToggleButton.tsx +1 -1
- package/src/components/FormElements/index.ts +1 -0
- package/src/components/FormStation/FormStation.stories.tsx +9 -0
- package/src/components/FormStation/FormStation.tsx +1 -1
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.spec.tsx +1 -1
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.tsx +1 -1
- package/src/components/Utils/Postgraphile/index.ts +3 -3
- package/src/components/Utils/Transformers/Timestamp.spec.ts +2 -2
- package/src/components/Utils/Transformers/Timestamp.ts +5 -1
- package/src/components/index.ts +1 -1
- package/src/helpers/utils.ts +17 -0
- package/src/styles/variables.scss +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axinom/mosaic-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0-rc.0",
|
|
4
4
|
"description": "UI components for building Axinom Mosaic applications",
|
|
5
5
|
"author": "Axinom",
|
|
6
6
|
"license": "PROPRIETARY",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"build-storybook": "storybook build"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@axinom/mosaic-core": "^0.4.
|
|
35
|
+
"@axinom/mosaic-core": "^0.4.5-rc.0",
|
|
36
36
|
"@faker-js/faker": "^7.4.0",
|
|
37
37
|
"@popperjs/core": "^2.9.2",
|
|
38
38
|
"clsx": "^1.1.0",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"luxon": "^3.3.0",
|
|
41
41
|
"react-calendar": "^3.3.1",
|
|
42
42
|
"react-content-loader": "^6.0.3",
|
|
43
|
+
"react-imask": "^6.4.3",
|
|
43
44
|
"react-popper": "^2.2.5",
|
|
44
45
|
"react-transition-group": "^4.3.0",
|
|
45
46
|
"yup": "^0.32.11"
|
|
@@ -101,5 +102,5 @@
|
|
|
101
102
|
"publishConfig": {
|
|
102
103
|
"access": "public"
|
|
103
104
|
},
|
|
104
|
-
"gitHead": "
|
|
105
|
+
"gitHead": "d99f62328986c3250b0491a0b8b5f55d89b66840"
|
|
105
106
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { mount, shallow } from 'enzyme';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { act } from 'react-dom/test-utils';
|
|
4
|
-
import {
|
|
4
|
+
import { BrowserRouter as Router, Link } from 'react-router-dom';
|
|
5
5
|
import { noop } from '../../../helpers/utils';
|
|
6
6
|
import { TextButton } from '../../Buttons';
|
|
7
|
-
import {
|
|
7
|
+
import { ConfirmationConfig, ConfirmDialog } from '../../ConfirmDialog';
|
|
8
8
|
import { IconName, Icons } from '../../Icons';
|
|
9
9
|
import {
|
|
10
10
|
Action,
|
|
@@ -2,8 +2,8 @@ import clsx from 'clsx';
|
|
|
2
2
|
import React, { useEffect, useState } from 'react';
|
|
3
3
|
import { Link } from 'react-router-dom';
|
|
4
4
|
import {
|
|
5
|
-
ConfirmDialog,
|
|
6
5
|
ConfirmationConfig,
|
|
6
|
+
ConfirmDialog,
|
|
7
7
|
useConfirmationDelay,
|
|
8
8
|
} from '../../ConfirmDialog';
|
|
9
9
|
import { IconName, Icons } from '../../Icons';
|
|
@@ -35,6 +35,8 @@
|
|
|
35
35
|
white-space: nowrap;
|
|
36
36
|
text-overflow: ellipsis;
|
|
37
37
|
overflow: hidden;
|
|
38
|
+
|
|
39
|
+
padding: 2px;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
.position,
|
|
@@ -56,6 +58,7 @@
|
|
|
56
58
|
grid-template-columns: 1fr 1fr;
|
|
57
59
|
|
|
58
60
|
justify-items: start;
|
|
61
|
+
align-items: center;
|
|
59
62
|
|
|
60
63
|
opacity: 0.5;
|
|
61
64
|
|
|
@@ -110,8 +113,9 @@
|
|
|
110
113
|
}
|
|
111
114
|
|
|
112
115
|
.actionButtonContainer {
|
|
116
|
+
display: grid;
|
|
113
117
|
height: 100%;
|
|
114
|
-
align-items:
|
|
118
|
+
align-items: center;
|
|
115
119
|
|
|
116
120
|
.actionButton {
|
|
117
121
|
height: 50px;
|
|
@@ -7,49 +7,4 @@
|
|
|
7
7
|
display: grid;
|
|
8
8
|
grid-template-columns: 1fr;
|
|
9
9
|
grid-template-rows: min-content min-content;
|
|
10
|
-
|
|
11
|
-
input {
|
|
12
|
-
width: 100%;
|
|
13
|
-
box-sizing: border-box;
|
|
14
|
-
height: var(--dynamic-list-input-height, $dynamic-list-input-height);
|
|
15
|
-
padding: 0 6px;
|
|
16
|
-
|
|
17
|
-
color: var(--input-color, $input-color);
|
|
18
|
-
font-size: var(--label-font-size, $label-font-size);
|
|
19
|
-
|
|
20
|
-
border: 1px solid var(--input-border-color, $input-border-color);
|
|
21
|
-
outline: none;
|
|
22
|
-
|
|
23
|
-
overflow: hidden;
|
|
24
|
-
white-space: nowrap;
|
|
25
|
-
text-overflow: ellipsis;
|
|
26
|
-
|
|
27
|
-
transition: box-shadow 0.15s ease-in-out 0s;
|
|
28
|
-
|
|
29
|
-
padding: 0 12px 0 12px;
|
|
30
|
-
|
|
31
|
-
&.hasError {
|
|
32
|
-
border: 1px solid
|
|
33
|
-
var(--input-invalid-border-color, $input-invalid-border-color);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
input:hover:enabled,
|
|
38
|
-
input:focus {
|
|
39
|
-
border: 1px solid var(--input-hover-color, $input-hover-color);
|
|
40
|
-
box-shadow: inset 0 0 0 2px var(--input-hover-color, $input-hover-color);
|
|
41
|
-
|
|
42
|
-
&.hasError {
|
|
43
|
-
border: 1px solid
|
|
44
|
-
var(--input-invalid-border-color, $input-invalid-border-color);
|
|
45
|
-
box-shadow: inset 0 0 0 2px
|
|
46
|
-
var(--input-invalid-hover-color, $input-invalid-hover-color);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
> small {
|
|
51
|
-
padding: 6px 0;
|
|
52
|
-
white-space: normal;
|
|
53
|
-
color: var(--input-invalid-color, $input-invalid-color);
|
|
54
|
-
}
|
|
55
10
|
}
|
|
@@ -43,66 +43,6 @@ describe('createInputRenderer', () => {
|
|
|
43
43
|
expect(wrapper).toBeTruthy();
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
it(`renders an 'id' attribute on the 'input' element if set`, () => {
|
|
47
|
-
const mockId = 'test-id';
|
|
48
|
-
const wrapper = mount(<RendererWrapper id={mockId} />);
|
|
49
|
-
|
|
50
|
-
const input = wrapper.find('input');
|
|
51
|
-
|
|
52
|
-
expect(input.prop('id')).toBe(mockId);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it(`renders a 'name' attribute on the 'input' element if set`, () => {
|
|
56
|
-
const mockName = 'test-name';
|
|
57
|
-
const wrapper = mount(<RendererWrapper name={mockName} />);
|
|
58
|
-
|
|
59
|
-
const input = wrapper.find('input');
|
|
60
|
-
|
|
61
|
-
expect(input.prop('name')).toBe(mockName);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it(`renders a 'type' attribute on the 'input' element if set`, () => {
|
|
65
|
-
const mockType = 'test-type';
|
|
66
|
-
const wrapper = mount(<RendererWrapper type={mockType} />);
|
|
67
|
-
|
|
68
|
-
const input = wrapper.find('input');
|
|
69
|
-
|
|
70
|
-
expect(input.prop('type')).toBe(mockType);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('renders "disabled" attribute on the "input" element with value "false" if not set otherwise', () => {
|
|
74
|
-
const wrapper = mount(<RendererWrapper />);
|
|
75
|
-
|
|
76
|
-
const input = wrapper.find('input');
|
|
77
|
-
|
|
78
|
-
expect(input.prop('disabled')).toBe(false);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it('renders "disabled" attribute on the "input" element if set', () => {
|
|
82
|
-
const wrapper = mount(<RendererWrapper disabled={true} />);
|
|
83
|
-
|
|
84
|
-
const input = wrapper.find('input');
|
|
85
|
-
|
|
86
|
-
expect(input.prop('disabled')).toBe(true);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it(`doesn't render placeholder by default`, () => {
|
|
90
|
-
const wrapper = mount(<RendererWrapper />);
|
|
91
|
-
|
|
92
|
-
const input = wrapper.find('input');
|
|
93
|
-
|
|
94
|
-
expect(input.prop('placeholder')).toBeUndefined();
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it(`renders a 'placeholder' attribute on the 'input' element if set`, () => {
|
|
98
|
-
const mockPlaceholder = 'test-placeholder';
|
|
99
|
-
const wrapper = mount(<RendererWrapper placeholder={mockPlaceholder} />);
|
|
100
|
-
|
|
101
|
-
const input = wrapper.find('input');
|
|
102
|
-
|
|
103
|
-
expect(input.prop('placeholder')).toBe(mockPlaceholder);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
46
|
it(`sets 'input' value to current value`, () => {
|
|
107
47
|
const mockValue = 'test-value';
|
|
108
48
|
const wrapper = mount(<RendererWrapper currentValue={mockValue} />);
|
|
@@ -144,7 +84,9 @@ describe('createInputRenderer', () => {
|
|
|
144
84
|
const input = wrapper.find('input');
|
|
145
85
|
|
|
146
86
|
act(() => {
|
|
147
|
-
input.simulate('change', {
|
|
87
|
+
input.simulate('change', {
|
|
88
|
+
target: { value: mockStringifiedNumber },
|
|
89
|
+
});
|
|
148
90
|
});
|
|
149
91
|
|
|
150
92
|
expect(onValueChangeSpy).toHaveBeenCalledTimes(1);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import clsx from 'clsx';
|
|
2
1
|
import React, { ChangeEvent } from 'react';
|
|
3
2
|
import { DynamicListDataEntryRenderer } from '../../../../DynamicDataList/DynamicDataList.model';
|
|
3
|
+
import { SingleLineText } from '../../../../FormElements';
|
|
4
4
|
import { CreateInputRendererConfig } from '../renderers.model';
|
|
5
5
|
import classes from './createInputRenderer.scss';
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ import classes from './createInputRenderer.scss';
|
|
|
11
11
|
*/
|
|
12
12
|
export const createInputRenderer = ({
|
|
13
13
|
id,
|
|
14
|
-
name,
|
|
14
|
+
name = '',
|
|
15
15
|
placeholder,
|
|
16
16
|
type = 'text',
|
|
17
17
|
transform = (value: string) => value,
|
|
@@ -27,19 +27,18 @@ export const createInputRenderer = ({
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
return (
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
</div>
|
|
30
|
+
<SingleLineText
|
|
31
|
+
id={id}
|
|
32
|
+
name={name}
|
|
33
|
+
type={type}
|
|
34
|
+
disabled={disabled}
|
|
35
|
+
placeholder={placeholder}
|
|
36
|
+
onChange={onChangeHandler}
|
|
37
|
+
inlineMode={true}
|
|
38
|
+
error={error}
|
|
39
|
+
className={classes.container}
|
|
40
|
+
value={(currentValue as string) ?? ''}
|
|
41
|
+
/>
|
|
43
42
|
);
|
|
44
43
|
};
|
|
45
44
|
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
|
|
51
51
|
select:hover {
|
|
52
52
|
border: 1px solid var(--input-hover-color, $input-hover-color);
|
|
53
|
-
box-shadow:
|
|
53
|
+
box-shadow: 0 0 0 2px var(--input-hover-color, $input-hover-color);
|
|
54
54
|
|
|
55
55
|
&.hasError {
|
|
56
56
|
border: 1px solid
|
|
57
57
|
var(--input-invalid-border-color, $input-invalid-border-color);
|
|
58
|
-
box-shadow:
|
|
58
|
+
box-shadow: 0 0 0 2px
|
|
59
59
|
var(--input-invalid-hover-color, $input-invalid-hover-color);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { BaseFormControl, SingleLineTextProps } from '../../../FormElements';
|
|
2
|
+
|
|
1
3
|
export interface BaseRendererConfig {
|
|
2
4
|
/** id html element id attribute */
|
|
3
|
-
id?:
|
|
5
|
+
id?: BaseFormControl['id'];
|
|
4
6
|
/** element name attribute */
|
|
5
|
-
name?:
|
|
7
|
+
name?: BaseFormControl['name'];
|
|
6
8
|
/** element placeholder attribute */
|
|
7
9
|
placeholder?: string;
|
|
8
10
|
/** Optional transformer that will change the final value to match the return value */
|
|
@@ -10,8 +12,8 @@ export interface BaseRendererConfig {
|
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
export interface CreateInputRendererConfig extends BaseRendererConfig {
|
|
13
|
-
/**
|
|
14
|
-
type?:
|
|
15
|
+
/** Input element type */
|
|
16
|
+
type?: SingleLineTextProps['type'];
|
|
15
17
|
/** optional transformer that will change the current value with each keypress. does not work with 'mask' prop. mainly used for trim(). */
|
|
16
18
|
transform?: (value: string) => unknown;
|
|
17
19
|
}
|
|
@@ -2,8 +2,8 @@ export * from './DynamicDataList';
|
|
|
2
2
|
export * from './DynamicDataList.model';
|
|
3
3
|
export * from './DynamicListDataEntry';
|
|
4
4
|
export {
|
|
5
|
-
CreateInputRendererConfig,
|
|
6
|
-
CreateSelectRendererConfig,
|
|
7
5
|
createInputRenderer,
|
|
6
|
+
CreateInputRendererConfig,
|
|
8
7
|
createSelectRenderer,
|
|
8
|
+
CreateSelectRendererConfig,
|
|
9
9
|
} from './DynamicListDataEntry/Renderers';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { mount, shallow } from 'enzyme';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { MessageBar } from '../MessageBar';
|
|
4
|
-
import { PageHeader } from '../PageHeader';
|
|
5
4
|
import { StationError } from '../models';
|
|
5
|
+
import { PageHeader } from '../PageHeader';
|
|
6
6
|
import { EmptyStation, EmptyStationProps } from './EmptyStation';
|
|
7
7
|
|
|
8
8
|
describe('EmptyStation', () => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import React, { PropsWithChildren } from 'react';
|
|
3
3
|
import { MessageBar, MessageBarProps } from '../MessageBar';
|
|
4
|
-
import { PageHeader, PageHeaderProps } from '../PageHeader';
|
|
5
4
|
import { StationError } from '../models';
|
|
5
|
+
import { PageHeader, PageHeaderProps } from '../PageHeader';
|
|
6
6
|
import classes from './EmptyStation.scss';
|
|
7
7
|
|
|
8
8
|
export type EmptyStationProps = PageHeaderProps & {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import { LocationDescriptor } from 'history';
|
|
3
3
|
import {
|
|
4
|
-
ForwardedRef,
|
|
5
4
|
default as React,
|
|
5
|
+
ForwardedRef,
|
|
6
6
|
useCallback,
|
|
7
7
|
useEffect,
|
|
8
8
|
useState,
|
|
@@ -22,9 +22,9 @@ import {
|
|
|
22
22
|
ListSelectMode,
|
|
23
23
|
SortData,
|
|
24
24
|
} from '../List';
|
|
25
|
+
import { ErrorType } from '../models';
|
|
25
26
|
import { PageHeader, PageHeaderActionProps } from '../PageHeader';
|
|
26
27
|
import { getState, storeState } from '../Utils/State/GlobalState';
|
|
27
|
-
import { ErrorType } from '../models';
|
|
28
28
|
import {
|
|
29
29
|
ExplorerBulkAction,
|
|
30
30
|
ExplorerDataProvider,
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
-moz-appearance: none;
|
|
6
6
|
-webkit-appearance: none;
|
|
7
7
|
appearance: none;
|
|
8
|
-
cursor: pointer;
|
|
9
8
|
color: var(--input-color, $input-color);
|
|
10
9
|
border: 1px solid var(--input-border-color, $input-border-color);
|
|
11
10
|
width: max-content;
|
|
@@ -34,6 +33,10 @@
|
|
|
34
33
|
border: 1px solid
|
|
35
34
|
var(--input-invalid-border-color, $input-invalid-border-color);
|
|
36
35
|
}
|
|
36
|
+
|
|
37
|
+
&:enabled {
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
}
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
input:hover:enabled {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import React, { useRef, useState } from 'react';
|
|
3
3
|
import {
|
|
4
|
-
ConfirmDialog,
|
|
5
4
|
ConfirmationConfig,
|
|
6
5
|
ConfirmationMode,
|
|
6
|
+
ConfirmDialog,
|
|
7
7
|
} from '../../ConfirmDialog';
|
|
8
8
|
import { BaseFormControl, BaseInputEvents } from '../Form.models';
|
|
9
9
|
import { FormElementContainer } from '../FormElementContainer';
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
|
-
import React, {
|
|
2
|
+
import React, {
|
|
3
|
+
ChangeEvent,
|
|
4
|
+
FormEvent,
|
|
5
|
+
useEffect,
|
|
6
|
+
useRef,
|
|
7
|
+
useState,
|
|
8
|
+
} from 'react';
|
|
3
9
|
import { CSSTransition, TransitionGroup } from 'react-transition-group';
|
|
4
10
|
import { noop } from '../../../helpers/utils';
|
|
5
11
|
import { useDebounce } from '../../../hooks/useDebounce/useDebounce';
|
|
@@ -84,7 +90,7 @@ export const CustomTags: React.FC<CustomTagsProps> = ({
|
|
|
84
90
|
...ref.current,
|
|
85
91
|
|
|
86
92
|
currentTarget: { value: currentTags as unknown as string },
|
|
87
|
-
} as React.
|
|
93
|
+
} as React.ChangeEvent<HTMLInputElement>);
|
|
88
94
|
|
|
89
95
|
// Resets event data
|
|
90
96
|
ref.current = undefined;
|
|
@@ -266,7 +272,7 @@ export const CustomTags: React.FC<CustomTagsProps> = ({
|
|
|
266
272
|
* Called when a user focuses out of the input
|
|
267
273
|
* @param e Input form event
|
|
268
274
|
*/
|
|
269
|
-
const onBlurHandler = (e:
|
|
275
|
+
const onBlurHandler = (e: ChangeEvent<HTMLInputElement>): void => {
|
|
270
276
|
onBlur(e);
|
|
271
277
|
|
|
272
278
|
// reset input if value is only whitespaces
|
|
@@ -280,7 +286,7 @@ export const CustomTags: React.FC<CustomTagsProps> = ({
|
|
|
280
286
|
currentTarget: {
|
|
281
287
|
value: textInput.current?.value ?? '',
|
|
282
288
|
},
|
|
283
|
-
} as
|
|
289
|
+
} as ChangeEvent<HTMLInputElement>);
|
|
284
290
|
};
|
|
285
291
|
|
|
286
292
|
return (
|
|
@@ -12,8 +12,7 @@ export const DateTimeTextField: React.FC<Omit<DateTimeTextProps, 'error'>> = (
|
|
|
12
12
|
props,
|
|
13
13
|
) => {
|
|
14
14
|
const error = useFormikError(props.name);
|
|
15
|
-
|
|
16
|
-
const [field, meta, helpers] = useField(props.name);
|
|
15
|
+
const [, meta, helpers] = useField(props.name);
|
|
17
16
|
|
|
18
17
|
const handleChange = (value: string | null, valid?: boolean): void => {
|
|
19
18
|
if (!valid) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FormEvent, ReactNode } from 'react';
|
|
1
|
+
import { ChangeEvent, FormEvent, ReactNode } from 'react';
|
|
2
2
|
|
|
3
3
|
export interface BaseFormElement {
|
|
4
4
|
/** Form control id */
|
|
@@ -24,11 +24,11 @@ export interface BaseFormControl extends BaseFormElement {
|
|
|
24
24
|
|
|
25
25
|
export interface BaseInputEvents {
|
|
26
26
|
/** Raised when the value has changed */
|
|
27
|
-
onChange?: (event:
|
|
27
|
+
onChange?: (event: ChangeEvent<HTMLInputElement>) => void;
|
|
28
28
|
/** Raised when the element has been selected */
|
|
29
|
-
onBlur?: (event:
|
|
29
|
+
onBlur?: (event: ChangeEvent<HTMLInputElement>) => void;
|
|
30
30
|
/** Raised when the element has been de-selected */
|
|
31
|
-
onFocus?: (event:
|
|
31
|
+
onFocus?: (event: ChangeEvent<HTMLInputElement>) => void;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export interface BaseSelectEvents {
|
|
@@ -78,7 +78,14 @@ export const FormElementContainer: React.FC<FormElementContainerProps> = ({
|
|
|
78
78
|
>
|
|
79
79
|
{children}
|
|
80
80
|
</div>
|
|
81
|
-
{error &&
|
|
81
|
+
{error && (
|
|
82
|
+
<small
|
|
83
|
+
className={clsx({ [classes.inlineMode]: inlineMode }, classes.error)}
|
|
84
|
+
data-test-id="form-field-error"
|
|
85
|
+
>
|
|
86
|
+
{error}
|
|
87
|
+
</small>
|
|
88
|
+
)}
|
|
82
89
|
</div>
|
|
83
90
|
);
|
|
84
91
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { shallow } from 'enzyme';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { noop } from '../../../helpers/utils';
|
|
4
|
+
import { MaskedSingleLineText } from './MaskedSingleLineText';
|
|
5
|
+
|
|
6
|
+
const defaultProps = {
|
|
7
|
+
name: 'timestamp',
|
|
8
|
+
label: 'Timestamp',
|
|
9
|
+
mask: '000',
|
|
10
|
+
onChange: noop,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
describe('MaskedSingleLineText', () => {
|
|
14
|
+
it('should render the component without crashing', () => {
|
|
15
|
+
const wrapper = shallow(<MaskedSingleLineText {...defaultProps} />);
|
|
16
|
+
|
|
17
|
+
expect(wrapper).toBeTruthy();
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { action } from '@storybook/addon-actions';
|
|
2
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import { createGroups } from '../../../helpers/storybook';
|
|
5
|
+
import { MaskedSingleLineText } from './MaskedSingleLineText';
|
|
6
|
+
|
|
7
|
+
const groups = createGroups({
|
|
8
|
+
Behavior: [
|
|
9
|
+
'autoComplete',
|
|
10
|
+
'autoFocus',
|
|
11
|
+
'disabled',
|
|
12
|
+
'inlineMode',
|
|
13
|
+
'name',
|
|
14
|
+
'id',
|
|
15
|
+
'innerRef',
|
|
16
|
+
'mask',
|
|
17
|
+
'overwrite',
|
|
18
|
+
'placeholderChar',
|
|
19
|
+
'lazy',
|
|
20
|
+
],
|
|
21
|
+
Content: [
|
|
22
|
+
'label',
|
|
23
|
+
'placeholder',
|
|
24
|
+
'error',
|
|
25
|
+
'tooltipContent',
|
|
26
|
+
'value',
|
|
27
|
+
'defaultValue',
|
|
28
|
+
],
|
|
29
|
+
Styling: ['className'],
|
|
30
|
+
Events: ['onChange', 'onBlur', 'onFocus'],
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const meta: Meta<typeof MaskedSingleLineText> = {
|
|
34
|
+
title: 'Primary Components/Form Elements/MaskedSingleLineText',
|
|
35
|
+
component: MaskedSingleLineText,
|
|
36
|
+
argTypes: {
|
|
37
|
+
...groups,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
export default meta;
|
|
41
|
+
|
|
42
|
+
export const Main: StoryObj<typeof MaskedSingleLineText> = {
|
|
43
|
+
args: {
|
|
44
|
+
name: 'timestamp',
|
|
45
|
+
label: 'Timestamp',
|
|
46
|
+
mask: '00:00:00.000',
|
|
47
|
+
placeholderChar: '0',
|
|
48
|
+
lazy: false,
|
|
49
|
+
},
|
|
50
|
+
render: (args) =>
|
|
51
|
+
React.createElement(() => {
|
|
52
|
+
const [value, setValue] = useState<string>();
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<MaskedSingleLineText
|
|
56
|
+
{...args}
|
|
57
|
+
value={value}
|
|
58
|
+
onChange={(e) => {
|
|
59
|
+
action('onChange')(e);
|
|
60
|
+
setValue(value);
|
|
61
|
+
}}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
}),
|
|
65
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
|
+
import { useIMask } from 'react-imask';
|
|
3
|
+
import {
|
|
4
|
+
SingleLineText,
|
|
5
|
+
SingleLineTextProps,
|
|
6
|
+
} from '../SingleLineText/SingleLineText';
|
|
7
|
+
|
|
8
|
+
export interface MaskedSingleLineTextProps
|
|
9
|
+
extends Omit<SingleLineTextProps, 'onChange' | 'type' | 'value' | 'isSet'> {
|
|
10
|
+
/** Expression to be used as a validator.
|
|
11
|
+
* Refer https://imask.js.org/guide.html#masked-pattern for examples
|
|
12
|
+
*/
|
|
13
|
+
mask: string;
|
|
14
|
+
|
|
15
|
+
/** Placeholder character for the mask */
|
|
16
|
+
placeholderChar?: string;
|
|
17
|
+
|
|
18
|
+
/** Current value the form control has */
|
|
19
|
+
value?: string;
|
|
20
|
+
|
|
21
|
+
/** Whether the mask should not be shown by default. (default: true) */
|
|
22
|
+
lazy?: boolean;
|
|
23
|
+
|
|
24
|
+
/** Whether new inputs should overwrite existing text. (default: false) */
|
|
25
|
+
overwrite?: boolean;
|
|
26
|
+
|
|
27
|
+
/** Raised when the value has changed */
|
|
28
|
+
onChange: (value: string) => unknown;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const MaskedSingleLineText: React.FC<MaskedSingleLineTextProps> = ({
|
|
32
|
+
onChange,
|
|
33
|
+
mask,
|
|
34
|
+
placeholderChar = '_',
|
|
35
|
+
value: formikValue = '',
|
|
36
|
+
lazy = true,
|
|
37
|
+
overwrite = false,
|
|
38
|
+
...props
|
|
39
|
+
}) => {
|
|
40
|
+
const { ref, maskRef } = useIMask(
|
|
41
|
+
{ mask, placeholderChar, lazy, overwrite },
|
|
42
|
+
{
|
|
43
|
+
onAccept: (value, _ref, e) => {
|
|
44
|
+
// OnChange shouldn't be used https://github.com/uNmAnNeR/imaskjs/issues/318
|
|
45
|
+
// OnAccept fires during initial load making the form dirty. However, the synthetic event is not
|
|
46
|
+
// present when this happens so we check for the event to see if it's actually a keyboard event
|
|
47
|
+
// that triggered onAccept.
|
|
48
|
+
if (e) {
|
|
49
|
+
onChange(value);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
maskRef.current.value = formikValue as string;
|
|
57
|
+
}, [formikValue, maskRef]);
|
|
58
|
+
|
|
59
|
+
return <SingleLineText innerRef={ref} type="text" {...props} />;
|
|
60
|
+
};
|