@griddo/ax 1.75.47 → 1.75.49
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/config/webpack.config.js +5 -0
- package/package.json +2 -2
- package/src/__tests__/components/Fields/CheckGroup/CheckGroup.test.tsx +93 -0
- package/src/__tests__/components/Fields/MultiCheckSelectGroup/MultiCheckSelectGroup.test.tsx +62 -0
- package/src/__tests__/components/Fields/NumberField/NumberField.test.tsx +20 -2
- package/src/__tests__/components/Toast/Toast.test.tsx +7 -0
- package/src/components/Fields/AsyncSelect/style.tsx +4 -2
- package/src/components/Fields/CheckGroup/index.tsx +7 -3
- package/src/components/Fields/MultiCheckSelectGroup/index.tsx +13 -5
- package/src/components/Fields/NumberField/index.tsx +4 -4
- package/src/components/Fields/Select/style.tsx +4 -2
- package/src/components/Toast/index.tsx +8 -4
- package/src/components/Toast/style.tsx +47 -47
package/config/webpack.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@griddo/ax",
|
|
3
3
|
"description": "Griddo Author Experience",
|
|
4
|
-
"version": "1.75.
|
|
4
|
+
"version": "1.75.49",
|
|
5
5
|
"authors": [
|
|
6
6
|
"Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
|
|
7
7
|
"Carlos Torres <carlos.torres@secuoyas.com>",
|
|
@@ -230,5 +230,5 @@
|
|
|
230
230
|
"publishConfig": {
|
|
231
231
|
"access": "public"
|
|
232
232
|
},
|
|
233
|
-
"gitHead": "
|
|
233
|
+
"gitHead": "759d80967ea9a653044c4e1bcfec932337e885b7"
|
|
234
234
|
}
|
|
@@ -56,6 +56,58 @@ describe("CheckField component rendering", () => {
|
|
|
56
56
|
expect(screen.findByTestId("check-group-field-group")).toBeTruthy();
|
|
57
57
|
expect(await screen.findAllByTestId("check-field-label")).toHaveLength(2);
|
|
58
58
|
});
|
|
59
|
+
|
|
60
|
+
it("should render the component with CheckField and no value", async () => {
|
|
61
|
+
const checkFieldOptions = [
|
|
62
|
+
{
|
|
63
|
+
name: "name 1",
|
|
64
|
+
value: 1,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "name 2",
|
|
68
|
+
value: 2,
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
const props = {
|
|
72
|
+
value: undefined,
|
|
73
|
+
options: checkFieldOptions,
|
|
74
|
+
onChange: jest.fn(),
|
|
75
|
+
};
|
|
76
|
+
render(
|
|
77
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
78
|
+
<CheckGroup {...props} />
|
|
79
|
+
</ThemeProvider>
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
expect(screen.findByTestId("check-group-field-group")).toBeTruthy();
|
|
83
|
+
expect(await screen.findAllByTestId("check-field-label")).toHaveLength(2);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("should render the component with CheckField and value null", async () => {
|
|
87
|
+
const checkFieldOptions = [
|
|
88
|
+
{
|
|
89
|
+
name: "name 1",
|
|
90
|
+
value: 1,
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: "name 2",
|
|
94
|
+
value: 2,
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
const props = {
|
|
98
|
+
value: null,
|
|
99
|
+
options: checkFieldOptions,
|
|
100
|
+
onChange: jest.fn(),
|
|
101
|
+
};
|
|
102
|
+
render(
|
|
103
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
104
|
+
<CheckGroup {...props} />
|
|
105
|
+
</ThemeProvider>
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
expect(screen.findByTestId("check-group-field-group")).toBeTruthy();
|
|
109
|
+
expect(await screen.findAllByTestId("check-field-label")).toHaveLength(2);
|
|
110
|
+
});
|
|
59
111
|
});
|
|
60
112
|
|
|
61
113
|
describe("CheckField events", () => {
|
|
@@ -259,4 +311,45 @@ describe("CheckField events", () => {
|
|
|
259
311
|
expect(onChangeMock).toHaveBeenCalledTimes(2);
|
|
260
312
|
expect(onChangeMock).toBeCalledWith(["surname"]);
|
|
261
313
|
});
|
|
314
|
+
|
|
315
|
+
it("should pass two selected values in the onchange call and remove not valid default value", async () => {
|
|
316
|
+
const checkFieldOptions = [
|
|
317
|
+
{
|
|
318
|
+
name: "all",
|
|
319
|
+
value: 1,
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
name: "name",
|
|
323
|
+
value: 2,
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
name: "surname",
|
|
327
|
+
value: 3,
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
name: "surname 2",
|
|
331
|
+
value: 4,
|
|
332
|
+
},
|
|
333
|
+
];
|
|
334
|
+
const onChangeMock = jest.fn();
|
|
335
|
+
|
|
336
|
+
const props = {
|
|
337
|
+
value: ["novalid"],
|
|
338
|
+
options: checkFieldOptions,
|
|
339
|
+
selectAllOption: "all",
|
|
340
|
+
onChange: onChangeMock,
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
render(
|
|
344
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
345
|
+
<CheckGroup {...props} />
|
|
346
|
+
</ThemeProvider>
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
const checkFieldInputs = await screen.queryAllByTestId("check-field-input");
|
|
350
|
+
|
|
351
|
+
await user.type(checkFieldInputs[1], "name");
|
|
352
|
+
await user.type(checkFieldInputs[2], "surname");
|
|
353
|
+
expect(onChangeMock).toBeCalledWith(["name", "surname"]);
|
|
354
|
+
});
|
|
262
355
|
});
|
package/src/__tests__/components/Fields/MultiCheckSelectGroup/MultiCheckSelectGroup.test.tsx
CHANGED
|
@@ -117,4 +117,66 @@ describe("onChange events", () => {
|
|
|
117
117
|
],
|
|
118
118
|
});
|
|
119
119
|
});
|
|
120
|
+
|
|
121
|
+
it("should call onChange with empty object", async () => {
|
|
122
|
+
const onChange = jest.fn();
|
|
123
|
+
defaultProps.value = {};
|
|
124
|
+
defaultProps.note = "lorem ipsum";
|
|
125
|
+
defaultProps.elements = [
|
|
126
|
+
{
|
|
127
|
+
source: "NEWS_AREAS",
|
|
128
|
+
key: "NEWS_AREAS",
|
|
129
|
+
placeholder: "News Areas",
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
const Component = (
|
|
134
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
135
|
+
<MultiCheckSelectGroup {...defaultProps} onChange={onChange} />
|
|
136
|
+
</ThemeProvider>
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
const data = {
|
|
140
|
+
data: [
|
|
141
|
+
{
|
|
142
|
+
value: 4168,
|
|
143
|
+
label: "another page",
|
|
144
|
+
name: "another page",
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
value: 4111,
|
|
148
|
+
label: "New Page",
|
|
149
|
+
name: "New Page",
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
status: 200,
|
|
153
|
+
statusText: "Ok",
|
|
154
|
+
headers: {},
|
|
155
|
+
config: {},
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
mockedAxios.mockResolvedValue(data);
|
|
159
|
+
|
|
160
|
+
const { rerender } = render(Component);
|
|
161
|
+
|
|
162
|
+
const field = screen.getByTestId("field");
|
|
163
|
+
|
|
164
|
+
await act(async () => {
|
|
165
|
+
fireEvent.click(field);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
rerender(Component);
|
|
169
|
+
|
|
170
|
+
const checkFieldInputs = screen.getAllByTestId("check-field-input");
|
|
171
|
+
|
|
172
|
+
await act(async () => {
|
|
173
|
+
fireEvent.click(checkFieldInputs[0]);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
await act(async () => {
|
|
177
|
+
fireEvent.click(checkFieldInputs[0]);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
expect(onChange).toBeCalledWith({});
|
|
181
|
+
});
|
|
120
182
|
});
|
|
@@ -5,10 +5,12 @@ import { parseTheme } from "@ax/helpers";
|
|
|
5
5
|
import globalTheme from "@ax/themes/theme.json";
|
|
6
6
|
import { mock } from "jest-mock-extended";
|
|
7
7
|
import { render, screen, cleanup, fireEvent } from "@testing-library/react";
|
|
8
|
+
import userEvent from "@testing-library/user-event";
|
|
8
9
|
|
|
9
10
|
afterEach(cleanup);
|
|
10
11
|
|
|
11
12
|
const defaultProps = mock<INumberFieldProps>();
|
|
13
|
+
const user = userEvent.setup();
|
|
12
14
|
|
|
13
15
|
describe("NumberField component rendering", () => {
|
|
14
16
|
it("should render the component", () => {
|
|
@@ -41,7 +43,7 @@ describe("onClick events", () => {
|
|
|
41
43
|
|
|
42
44
|
it("should call onChange when clicking arrow down", () => {
|
|
43
45
|
defaultProps.value = 2;
|
|
44
|
-
defaultProps.
|
|
46
|
+
defaultProps.min = 1;
|
|
45
47
|
const onChange = jest.fn();
|
|
46
48
|
|
|
47
49
|
render(
|
|
@@ -77,7 +79,7 @@ describe("onBlur events", () => {
|
|
|
77
79
|
|
|
78
80
|
describe("onChange events", () => {
|
|
79
81
|
it("should call onChange on change", () => {
|
|
80
|
-
defaultProps.
|
|
82
|
+
defaultProps.max = 7;
|
|
81
83
|
defaultProps.error = true;
|
|
82
84
|
const onChange = jest.fn();
|
|
83
85
|
const handleValidation = jest.fn();
|
|
@@ -93,4 +95,20 @@ describe("onChange events", () => {
|
|
|
93
95
|
expect(onChange).toHaveBeenCalledWith(5);
|
|
94
96
|
expect(handleValidation).toHaveBeenCalled();
|
|
95
97
|
});
|
|
98
|
+
|
|
99
|
+
it("should call onChange with undefined", async () => {
|
|
100
|
+
defaultProps.value = undefined;
|
|
101
|
+
const onChange = jest.fn();
|
|
102
|
+
|
|
103
|
+
render(
|
|
104
|
+
<ThemeProvider theme={parseTheme(globalTheme)}>
|
|
105
|
+
<NumberField {...defaultProps} onChange={onChange} />
|
|
106
|
+
</ThemeProvider>
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const input = screen.getByTestId("input");
|
|
110
|
+
input.focus();
|
|
111
|
+
await user.keyboard("{4}{Backspace}");
|
|
112
|
+
expect(onChange).toHaveBeenCalledWith(undefined);
|
|
113
|
+
});
|
|
96
114
|
});
|
|
@@ -10,6 +10,13 @@ import globalTheme from "@ax/themes/theme.json";
|
|
|
10
10
|
|
|
11
11
|
afterEach(cleanup);
|
|
12
12
|
|
|
13
|
+
jest.mock("react-router-dom", () => ({
|
|
14
|
+
...jest.requireActual("react-router-dom"),
|
|
15
|
+
useLocation: () => ({
|
|
16
|
+
pathname: "localhost:3000/example/path",
|
|
17
|
+
}),
|
|
18
|
+
}));
|
|
19
|
+
|
|
13
20
|
const defaultProps = mock<IToastProps>();
|
|
14
21
|
|
|
15
22
|
describe("Toast component rendering", () => {
|
|
@@ -46,20 +46,22 @@ export const StyledSelect = styled(AsyncSelect)<{ isDisabled: boolean | undefine
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
.react-select__menu {
|
|
49
|
-
box-shadow:
|
|
49
|
+
box-shadow: none;
|
|
50
50
|
border-radius: 4px;
|
|
51
51
|
min-width: calc(${(p) => p.theme.spacing.xl} * 4);
|
|
52
52
|
max-width: calc(${(p) => p.theme.spacing.xl} * 6);
|
|
53
53
|
margin-top: 0;
|
|
54
54
|
z-index: 99;
|
|
55
55
|
.react-select__menu-list {
|
|
56
|
+
border: 1px solid ${(p) => p.theme.color.uiLine};
|
|
57
|
+
border-radius: 4px;
|
|
56
58
|
max-height: calc(${(p) => p.theme.spacing.l} * 3);
|
|
57
59
|
overflow: auto;
|
|
58
60
|
padding: 0;
|
|
59
61
|
.react-select__option {
|
|
60
62
|
background-color: ${(p) => p.theme.color.interactiveBackground};
|
|
61
63
|
min-height: ${(p) => p.theme.spacing.l};
|
|
62
|
-
padding: ${(p) => p.theme.spacing.s};
|
|
64
|
+
padding: ${(p) => `13px ${p.theme.spacing.s} 12px ${p.theme.spacing.s}`};
|
|
63
65
|
&:first-child {
|
|
64
66
|
${(p) =>
|
|
65
67
|
!p.mandatory &&
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
import * as S from "./style";
|
|
4
3
|
import { ICheck } from "@ax/types";
|
|
5
4
|
import CheckField, { ICheckFieldProps } from "../CheckField";
|
|
6
5
|
|
|
6
|
+
import * as S from "./style";
|
|
7
|
+
|
|
7
8
|
const CheckGroup = (props: ICheckGroupProps): JSX.Element => {
|
|
8
9
|
const { options, onChange, value, selectAllOption, multipleSelection = true, disabled } = props;
|
|
9
10
|
|
|
10
|
-
let valueArray = typeof value === "string" ? value.split(",") : value;
|
|
11
|
+
let valueArray = !value ? [] : typeof value === "string" ? value.split(",") : value;
|
|
12
|
+
valueArray = valueArray.filter((val: string | number) => options?.some((option) => option.value === val));
|
|
11
13
|
|
|
12
14
|
const handleChange = (newValue: ICheck) => {
|
|
13
15
|
const index = valueArray.indexOf(newValue.value);
|
|
16
|
+
|
|
14
17
|
if (index >= 0 && !newValue.isChecked) {
|
|
15
18
|
valueArray.splice(index, 1);
|
|
16
19
|
}
|
|
20
|
+
|
|
17
21
|
if (index < 0 && newValue.isChecked) {
|
|
18
22
|
valueArray.push(newValue.value);
|
|
19
23
|
}
|
|
@@ -56,7 +60,7 @@ const CheckGroup = (props: ICheckGroupProps): JSX.Element => {
|
|
|
56
60
|
};
|
|
57
61
|
|
|
58
62
|
interface ICheckGroupProps {
|
|
59
|
-
value: string | (string | number)[];
|
|
63
|
+
value: string | (string | number)[] | null | undefined;
|
|
60
64
|
options: ICheckFieldProps[] | undefined;
|
|
61
65
|
onChange: (value: string | (string | number)[]) => void;
|
|
62
66
|
selectAllOption?: string;
|
|
@@ -7,6 +7,8 @@ import * as S from "./style";
|
|
|
7
7
|
const MultiCheckSelectGroup = (props: IMultiCheckSelectGroupProps) => {
|
|
8
8
|
const { value, onChange, site, elements, note } = props;
|
|
9
9
|
|
|
10
|
+
const completedValue = value ? value : {};
|
|
11
|
+
|
|
10
12
|
return (
|
|
11
13
|
<>
|
|
12
14
|
{note && <S.StyledNoteField value={{ text: note }} />}
|
|
@@ -14,12 +16,18 @@ const MultiCheckSelectGroup = (props: IMultiCheckSelectGroupProps) => {
|
|
|
14
16
|
elements.map((element: any) => {
|
|
15
17
|
const { placeholder, source, key, mandatory, isGlobal } = element;
|
|
16
18
|
|
|
17
|
-
const handleChange = (val: any) => {
|
|
18
|
-
|
|
19
|
+
const handleChange = (val: any[]) => {
|
|
20
|
+
let newValue = { ...completedValue };
|
|
21
|
+
if (val.length > 0) {
|
|
22
|
+
newValue = { ...newValue, [key]: val };
|
|
23
|
+
} else {
|
|
24
|
+
delete newValue[key];
|
|
25
|
+
}
|
|
26
|
+
|
|
19
27
|
onChange(newValue);
|
|
20
28
|
};
|
|
21
29
|
|
|
22
|
-
const val =
|
|
30
|
+
const val = completedValue[key] ? completedValue[key] : [];
|
|
23
31
|
const fromSite = isGlobal ? null : site;
|
|
24
32
|
|
|
25
33
|
return (
|
|
@@ -39,9 +47,9 @@ const MultiCheckSelectGroup = (props: IMultiCheckSelectGroupProps) => {
|
|
|
39
47
|
};
|
|
40
48
|
|
|
41
49
|
export interface IMultiCheckSelectGroupProps {
|
|
42
|
-
value: any;
|
|
50
|
+
value: Record<string, any[]> | Record<string, never> | undefined | null;
|
|
43
51
|
elements: any[];
|
|
44
|
-
onChange: (value: string | string
|
|
52
|
+
onChange: (value: Record<string, any[]> | Record<string, never>) => void;
|
|
45
53
|
site?: ISite;
|
|
46
54
|
note?: string;
|
|
47
55
|
}
|
|
@@ -6,7 +6,7 @@ import * as S from "./style";
|
|
|
6
6
|
const NumberField = (props: INumberFieldProps): JSX.Element => {
|
|
7
7
|
const { name, value, error, onChange, onBlur, maxValue, minValue, disabled, handleValidation, min, max } = props;
|
|
8
8
|
|
|
9
|
-
const strValue = value ? value.toString() : "
|
|
9
|
+
const strValue = value || value === 0 ? value.toString() : "";
|
|
10
10
|
const safeMax = typeof max !== "undefined" ? max : maxValue;
|
|
11
11
|
const safeMin = typeof min !== "undefined" ? min : minValue;
|
|
12
12
|
|
|
@@ -17,7 +17,7 @@ const NumberField = (props: INumberFieldProps): JSX.Element => {
|
|
|
17
17
|
}, [strValue]);
|
|
18
18
|
|
|
19
19
|
const setValue = (value: string, eventType: string) => {
|
|
20
|
-
const floatValue = parseFloat(value);
|
|
20
|
+
const floatValue = value || value === "0" ? parseFloat(value) : undefined;
|
|
21
21
|
setInputValue(value);
|
|
22
22
|
|
|
23
23
|
eventType === "blur" ? onBlur && onBlur(floatValue) : onChange(floatValue);
|
|
@@ -85,7 +85,7 @@ const NumberField = (props: INumberFieldProps): JSX.Element => {
|
|
|
85
85
|
|
|
86
86
|
export interface INumberFieldProps {
|
|
87
87
|
value?: number;
|
|
88
|
-
onChange: (value: number) => void;
|
|
88
|
+
onChange: (value: number | null | undefined) => void;
|
|
89
89
|
name?: string;
|
|
90
90
|
error?: boolean;
|
|
91
91
|
minValue?: number; // to deprecate
|
|
@@ -93,7 +93,7 @@ export interface INumberFieldProps {
|
|
|
93
93
|
min?: number;
|
|
94
94
|
max?: number;
|
|
95
95
|
onClickIcon?: () => void;
|
|
96
|
-
onBlur?: (value: number) => void;
|
|
96
|
+
onBlur?: (value: number | null | undefined) => void;
|
|
97
97
|
disabled?: boolean;
|
|
98
98
|
handleValidation?: (value: string, validators: Record<string, unknown>) => void;
|
|
99
99
|
}
|
|
@@ -49,20 +49,22 @@ export const StyledSelect = styled(Select)<{
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
.react-select__menu {
|
|
52
|
-
box-shadow:
|
|
52
|
+
box-shadow: none;
|
|
53
53
|
border-radius: 4px;
|
|
54
54
|
min-width: calc(${(p) => p.theme.spacing?.xl} * 2);
|
|
55
55
|
max-width: calc(${(p) => p.theme.spacing?.xl} * 6);
|
|
56
56
|
margin-top: 0;
|
|
57
57
|
z-index: 99;
|
|
58
58
|
.react-select__menu-list {
|
|
59
|
+
border: 1px solid ${(p) => p.theme.color.uiLine};
|
|
60
|
+
border-radius: 4px;
|
|
59
61
|
max-height: calc(${(p) => p.theme.spacing?.l} * 3);
|
|
60
62
|
overflow: auto;
|
|
61
63
|
padding: 0;
|
|
62
64
|
.react-select__option {
|
|
63
65
|
background-color: ${(p) => p.theme.color?.interactiveBackground};
|
|
64
66
|
min-height: ${(p) => p.theme.spacing?.l};
|
|
65
|
-
padding: ${(p) => p.theme.spacing
|
|
67
|
+
padding: ${(p) => `13px ${p.theme.spacing.s} 12px ${p.theme.spacing.s}`};
|
|
66
68
|
&:first-child {
|
|
67
69
|
${(p) =>
|
|
68
70
|
p.hasEmptyOption &&
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import React, { useRef, useEffect } from "react";
|
|
2
|
+
import { useLocation } from "react-router-dom";
|
|
2
3
|
|
|
3
4
|
import { createPortal } from "react-dom";
|
|
4
5
|
import { Button, IconAction } from "@ax/components";
|
|
5
6
|
|
|
6
7
|
import * as S from "./style";
|
|
7
8
|
|
|
8
|
-
const Toast = (props: IToastProps) => {
|
|
9
|
+
const Toast = (props: IToastProps): JSX.Element => {
|
|
9
10
|
const { action, message, setIsVisible } = props;
|
|
10
11
|
const toast = useRef<any>(null);
|
|
11
12
|
|
|
13
|
+
const { pathname } = useLocation();
|
|
14
|
+
const isEditor = pathname.includes("/editor");
|
|
15
|
+
|
|
12
16
|
let temp: any;
|
|
13
17
|
const setTemp = (time: number) => (temp = setTimeout(() => setIsVisible(false), time));
|
|
14
18
|
|
|
@@ -24,14 +28,14 @@ const Toast = (props: IToastProps) => {
|
|
|
24
28
|
}, []);
|
|
25
29
|
|
|
26
30
|
return createPortal(
|
|
27
|
-
<S.Wrapper ref={toast} data-testid="toast-wrapper">
|
|
31
|
+
<S.Wrapper ref={toast} isEditor={isEditor} data-testid="toast-wrapper">
|
|
28
32
|
<S.Text data-testid="toast-message">{message}</S.Text>
|
|
29
33
|
<S.Buttons>
|
|
30
|
-
{action &&
|
|
34
|
+
{action && (
|
|
31
35
|
<Button type="button" buttonStyle="lineInverse" onClick={action}>
|
|
32
36
|
Undo
|
|
33
37
|
</Button>
|
|
34
|
-
}
|
|
38
|
+
)}
|
|
35
39
|
<IconAction icon="close" onClick={close} inversed={true} />
|
|
36
40
|
</S.Buttons>
|
|
37
41
|
</S.Wrapper>,
|
|
@@ -1,57 +1,57 @@
|
|
|
1
1
|
import styled from "styled-components";
|
|
2
2
|
|
|
3
|
-
const Wrapper = styled.div
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
3
|
+
const Wrapper = styled.div<{ isEditor: boolean }>`
|
|
4
|
+
width: 453px;
|
|
5
|
+
height: ${(p) => `calc(${p.theme.spacing.m} * 2)`};
|
|
6
|
+
background: ${(p) => p.theme.color.uiMainMenuBackground};
|
|
7
|
+
display: flex;
|
|
8
|
+
justify-content: space-between;
|
|
9
|
+
align-items: center;
|
|
10
|
+
border-radius: 4px;
|
|
11
|
+
position: fixed;
|
|
12
|
+
z-index: 1100;
|
|
13
|
+
bottom: ${(p) => p.theme.spacing.m};
|
|
14
|
+
left: ${(p) => (p.isEditor ? `calc(${p.theme.spacing.m} * 1)` : `calc(${p.theme.spacing.m} * 4)`)};
|
|
15
|
+
padding-left: ${(p) => p.theme.spacing.m};
|
|
16
|
+
padding-right: ${(p) => p.theme.spacing.s};
|
|
17
|
+
animation-name: transition;
|
|
18
|
+
animation-duration: 5s;
|
|
19
|
+
opacity: 0;
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
&.close-animation {
|
|
22
|
+
animation-name: transition-inversed;
|
|
23
|
+
animation-duration: 1s;
|
|
24
|
+
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
80% {
|
|
36
|
-
opacity: 1;
|
|
37
|
-
transform: translateX(0)
|
|
38
|
-
}
|
|
39
|
-
100% {
|
|
40
|
-
opacity: 0;
|
|
41
|
-
transform: translateX(-100%)
|
|
42
|
-
}
|
|
26
|
+
@keyframes transition {
|
|
27
|
+
0% {
|
|
28
|
+
opacity: 0;
|
|
29
|
+
transform: translateX(-100%);
|
|
30
|
+
}
|
|
31
|
+
20% {
|
|
32
|
+
opacity: 1;
|
|
33
|
+
transform: translateX(0);
|
|
43
34
|
}
|
|
35
|
+
80% {
|
|
36
|
+
opacity: 1;
|
|
37
|
+
transform: translateX(0);
|
|
38
|
+
}
|
|
39
|
+
100% {
|
|
40
|
+
opacity: 0;
|
|
41
|
+
transform: translateX(-100%);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
45
|
+
@keyframes transition-inversed {
|
|
46
|
+
from {
|
|
47
|
+
opacity: 1;
|
|
48
|
+
transform: translateX(0);
|
|
49
|
+
}
|
|
50
|
+
to {
|
|
51
|
+
opacity: 0;
|
|
52
|
+
transform: translateX(-100%);
|
|
54
53
|
}
|
|
54
|
+
}
|
|
55
55
|
`;
|
|
56
56
|
|
|
57
57
|
const Text = styled.div`
|