@griddo/ax 11.10.9-rc.1 → 11.10.10
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/package.json +3 -3
- package/src/__tests__/components/SideModal/SideModal.test.tsx +0 -3
- package/src/components/MenuItem/index.tsx +12 -2
- package/src/components/SearchField/index.tsx +10 -5
- package/src/components/SideModal/SideModalOption/index.tsx +7 -1
- package/src/components/SideModal/index.tsx +44 -21
- package/src/components/SideModal/style.tsx +16 -16
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@griddo/ax",
|
|
3
3
|
"description": "Griddo Author Experience",
|
|
4
|
-
"version": "11.10.
|
|
4
|
+
"version": "11.10.10",
|
|
5
5
|
"authors": [
|
|
6
6
|
"Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
|
|
7
7
|
"Diego M. Béjar <diego.bejar@secuoyas.com>",
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
"styled-system": "5.1.5",
|
|
145
145
|
"terser-webpack-plugin": "1.4.1",
|
|
146
146
|
"ts-pnp": "1.1.4",
|
|
147
|
-
"typescript": "
|
|
147
|
+
"typescript": "5.9.3",
|
|
148
148
|
"url-loader": "4.1.1",
|
|
149
149
|
"uuid": "8.3.2",
|
|
150
150
|
"webpack": "4.47.0",
|
|
@@ -225,5 +225,5 @@
|
|
|
225
225
|
"publishConfig": {
|
|
226
226
|
"access": "public"
|
|
227
227
|
},
|
|
228
|
-
"gitHead": "
|
|
228
|
+
"gitHead": "7ab8ffd85a8673602920d7f585c15e974a77dfe2"
|
|
229
229
|
}
|
|
@@ -284,10 +284,7 @@ describe("SideModal component events", () => {
|
|
|
284
284
|
<SideModal {...defaultProps} />
|
|
285
285
|
</ThemeProvider>
|
|
286
286
|
);
|
|
287
|
-
const filterButton = screen.getByTestId("icon-search-wrapper");
|
|
288
287
|
|
|
289
|
-
expect(filterButton).toBeTruthy();
|
|
290
|
-
fireEvent.click(filterButton);
|
|
291
288
|
const searchFieldWrapper = screen.getByTestId("search-field-wrapper");
|
|
292
289
|
expect(searchFieldWrapper).toBeTruthy();
|
|
293
290
|
const input = screen.getByTestId("search-input");
|
|
@@ -9,7 +9,14 @@ const MenuItem = (props: IMenuItemProps): JSX.Element => {
|
|
|
9
9
|
const handleOnClick = (e: React.MouseEvent<HTMLLIElement>) => {
|
|
10
10
|
if (onClick !== undefined && !disabled) {
|
|
11
11
|
e.preventDefault();
|
|
12
|
-
onClick(
|
|
12
|
+
onClick();
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const handleOnKeyDown = (e: React.KeyboardEvent<HTMLLIElement>) => {
|
|
17
|
+
if (e.key === "Enter" && onClick !== undefined && !disabled) {
|
|
18
|
+
e.preventDefault();
|
|
19
|
+
onClick();
|
|
13
20
|
}
|
|
14
21
|
};
|
|
15
22
|
|
|
@@ -25,6 +32,9 @@ const MenuItem = (props: IMenuItemProps): JSX.Element => {
|
|
|
25
32
|
onlyOnHover={(extendedAction && extendedAction.onlyOnHover) ?? true}
|
|
26
33
|
data-testid="menu-subitem"
|
|
27
34
|
disabled={disabled}
|
|
35
|
+
tabIndex={0}
|
|
36
|
+
onKeyDown={handleOnKeyDown}
|
|
37
|
+
role="button"
|
|
28
38
|
>
|
|
29
39
|
<div>{children}</div>
|
|
30
40
|
{extendedAction && (
|
|
@@ -40,7 +50,7 @@ const MenuItem = (props: IMenuItemProps): JSX.Element => {
|
|
|
40
50
|
|
|
41
51
|
export interface IMenuItemProps {
|
|
42
52
|
children: JSX.Element | string;
|
|
43
|
-
onClick?: (
|
|
53
|
+
onClick?: () => void;
|
|
44
54
|
extendedAction?: { icon: string; action?: () => void; onlyOnHover?: boolean } | null;
|
|
45
55
|
className?: string;
|
|
46
56
|
disabled?: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Icon } from "@ax/components";
|
|
2
|
-
import React, { useEffect, useState } from "react";
|
|
2
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
3
3
|
import { Select } from "../Fields";
|
|
4
4
|
|
|
5
5
|
import * as S from "./style";
|
|
@@ -22,6 +22,14 @@ const SearchField = (props: ISearchFieldProps): JSX.Element => {
|
|
|
22
22
|
const [isOpen, setIsOpen] = useState(value && value.trim() !== "" ? true : false);
|
|
23
23
|
const [inputValue, setInputValue] = useState(value || "");
|
|
24
24
|
const [selectValue, setSelectValue] = useState<string>("");
|
|
25
|
+
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
26
|
+
const showField = isOpen || !closeOnInactive;
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (focus && showField && inputRef.current) {
|
|
30
|
+
inputRef.current.focus();
|
|
31
|
+
}
|
|
32
|
+
}, [focus, showField]);
|
|
25
33
|
|
|
26
34
|
useEffect(() => {
|
|
27
35
|
if (value !== inputValue) {
|
|
@@ -66,8 +74,6 @@ const SearchField = (props: ISearchFieldProps): JSX.Element => {
|
|
|
66
74
|
onFilterChange && onFilterChange(value);
|
|
67
75
|
};
|
|
68
76
|
|
|
69
|
-
const showField = isOpen || !closeOnInactive;
|
|
70
|
-
|
|
71
77
|
return (
|
|
72
78
|
<S.Wrapper data-testid="search-field-wrapper">
|
|
73
79
|
{showField ? (
|
|
@@ -97,8 +103,7 @@ const SearchField = (props: ISearchFieldProps): JSX.Element => {
|
|
|
97
103
|
disabled={disabled}
|
|
98
104
|
data-testid="search-input"
|
|
99
105
|
small={small}
|
|
100
|
-
|
|
101
|
-
autoFocus={focus && showField}
|
|
106
|
+
ref={inputRef}
|
|
102
107
|
inputSize={size}
|
|
103
108
|
name="searchInput"
|
|
104
109
|
/>
|
|
@@ -29,6 +29,12 @@ const SideModalOption = (props: IProps) => {
|
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
+
const handleKeyDown = (e: React.KeyboardEvent) => {
|
|
33
|
+
if (e.key === "Enter") {
|
|
34
|
+
setOption();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
32
38
|
const defaultTag = option.tag ? (
|
|
33
39
|
<S.TagWrapper data-testid="side-modal-option-tag">
|
|
34
40
|
<Tag text={option.tag} type="square" />
|
|
@@ -36,7 +42,7 @@ const SideModalOption = (props: IProps) => {
|
|
|
36
42
|
) : null;
|
|
37
43
|
|
|
38
44
|
return (
|
|
39
|
-
<S.Item onClick={setOption} data-testid="side-modal-option">
|
|
45
|
+
<S.Item onClick={setOption} tabIndex={0} onKeyDown={handleKeyDown} role="button" data-testid="side-modal-option">
|
|
40
46
|
<S.Thumbnail data-testid="side-modal-option-img" {...thumbnailProps} />
|
|
41
47
|
{label}
|
|
42
48
|
{defaultTag}
|
|
@@ -37,6 +37,22 @@ const SideModal = (props: ISideModalProps): JSX.Element | null => {
|
|
|
37
37
|
const [searchQuery, setSearchQuery] = useState("");
|
|
38
38
|
const node = useRef<HTMLDivElement | null>(null);
|
|
39
39
|
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
const handleKeyPress = (event: KeyboardEvent) => {
|
|
42
|
+
if (event.key === "Escape") {
|
|
43
|
+
toggleModal();
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
if (isOpen) {
|
|
48
|
+
document.addEventListener("keydown", handleKeyPress);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return () => {
|
|
52
|
+
document.removeEventListener("keydown", handleKeyPress);
|
|
53
|
+
};
|
|
54
|
+
}, [isOpen, toggleModal]);
|
|
55
|
+
|
|
40
56
|
useEffect(() => {
|
|
41
57
|
if (componentOptions) {
|
|
42
58
|
for (const key in componentOptions) {
|
|
@@ -143,32 +159,39 @@ const SideModal = (props: ISideModalProps): JSX.Element | null => {
|
|
|
143
159
|
});
|
|
144
160
|
|
|
145
161
|
return createPortal(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
<S.
|
|
150
|
-
|
|
151
|
-
<S.SearchWrapper>
|
|
152
|
-
<SearchField onChange={setSearchQuery} closeOnInactive={true} small={!filters} value={searchQuery} />
|
|
153
|
-
</S.SearchWrapper>
|
|
154
|
-
)}
|
|
155
|
-
{!showSearch && (
|
|
162
|
+
<S.Wrapper ref={node} optionsType={optionsType} isOpen={isOpen} data-testid="side-modal">
|
|
163
|
+
{isOpen && (
|
|
164
|
+
<>
|
|
165
|
+
<S.Header>
|
|
166
|
+
<S.Title data-testid="side-modal-title">{optionsType}</S.Title>
|
|
156
167
|
<S.ButtonWrapper data-testid="side-modal-close-button">
|
|
157
168
|
<IconAction icon="close" onClick={handleCloseModal} />
|
|
158
169
|
</S.ButtonWrapper>
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
170
|
+
</S.Header>
|
|
171
|
+
<S.ColumnsWrapper>
|
|
172
|
+
{(filters || featuredFilters) && (
|
|
173
|
+
<S.FilterContent>
|
|
174
|
+
{featuredFilters && <S.FeaturedWrapper>{featuredFilters}</S.FeaturedWrapper>}
|
|
175
|
+
{filters && <div>{filters}</div>}
|
|
176
|
+
</S.FilterContent>
|
|
177
|
+
)}
|
|
163
178
|
<S.Content>
|
|
164
|
-
{
|
|
165
|
-
|
|
179
|
+
{showSearch && optionsType !== "components" && (
|
|
180
|
+
<S.SearchWrapper>
|
|
181
|
+
<SearchField
|
|
182
|
+
onChange={setSearchQuery}
|
|
183
|
+
value={searchQuery}
|
|
184
|
+
searchOnEnter={false}
|
|
185
|
+
placeholder="Search"
|
|
186
|
+
/>
|
|
187
|
+
</S.SearchWrapper>
|
|
188
|
+
)}
|
|
189
|
+
{filteredOptions}
|
|
166
190
|
</S.Content>
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
</>,
|
|
191
|
+
</S.ColumnsWrapper>
|
|
192
|
+
</>
|
|
193
|
+
)}
|
|
194
|
+
</S.Wrapper>,
|
|
172
195
|
document.body
|
|
173
196
|
);
|
|
174
197
|
};
|
|
@@ -18,9 +18,22 @@ const Header = styled.div`
|
|
|
18
18
|
}
|
|
19
19
|
`;
|
|
20
20
|
|
|
21
|
+
const FilterContent = styled.div`
|
|
22
|
+
list-style: none;
|
|
23
|
+
padding: ${(p) => p.theme.spacing.s};
|
|
24
|
+
height: ${(p) => `calc(100vh - ${p.theme.spacing.xl})`};
|
|
25
|
+
width: ${(p) => `calc(${p.theme.spacing.xl} * 3)`};
|
|
26
|
+
overflow: auto;
|
|
27
|
+
border-right: 1px solid ${(p) => p.theme.colors.uiLine};
|
|
28
|
+
&:last-child {
|
|
29
|
+
border-right: 0;
|
|
30
|
+
width: ${(p) => `calc(${p.theme.spacing.xl} * 4)`};
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
|
|
21
34
|
const Content = styled.div`
|
|
22
35
|
list-style: none;
|
|
23
|
-
padding: ${(p) => p.theme.spacing.m};
|
|
36
|
+
padding: ${(p) => `${p.theme.spacing.s} ${p.theme.spacing.m}`};
|
|
24
37
|
height: ${(p) => `calc(100vh - ${p.theme.spacing.xl})`};
|
|
25
38
|
width: ${(p) => `calc(${p.theme.spacing.xl} * 3)`};
|
|
26
39
|
overflow: auto;
|
|
@@ -43,20 +56,6 @@ const Wrapper = styled.div<{ optionsType?: string; isOpen: boolean }>`
|
|
|
43
56
|
box-shadow: ${(p) =>
|
|
44
57
|
p.optionsType && placeRight.includes(p.optionsType) ? p.theme.shadow.rightPanel : p.theme.shadow.leftPanel};
|
|
45
58
|
transition: all 0.5s ease-in-out;
|
|
46
|
-
|
|
47
|
-
&.form-fields {
|
|
48
|
-
margin-top: ${(p) => p.theme.spacing.xl};
|
|
49
|
-
|
|
50
|
-
${Header} {
|
|
51
|
-
padding: ${(p) => `${p.theme.spacing.s} ${p.theme.spacing.s} 0`};
|
|
52
|
-
background-color: transparent;
|
|
53
|
-
border-bottom: none;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
${Content} {
|
|
57
|
-
padding: ${(p) => p.theme.spacing.s};
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
59
|
`;
|
|
61
60
|
|
|
62
61
|
const Title = styled.h6`
|
|
@@ -78,7 +77,7 @@ const FeaturedWrapper = styled.div`
|
|
|
78
77
|
|
|
79
78
|
const SearchWrapper = styled.div`
|
|
80
79
|
width: 100%;
|
|
81
|
-
margin-
|
|
80
|
+
margin-bottom: ${(p) => p.theme.spacing.s};
|
|
82
81
|
`;
|
|
83
82
|
|
|
84
83
|
const Link = styled.div<{ active: boolean }>`
|
|
@@ -116,6 +115,7 @@ const ClosedFloatingButtonWrapper = styled.div`
|
|
|
116
115
|
|
|
117
116
|
export {
|
|
118
117
|
Wrapper,
|
|
118
|
+
FilterContent,
|
|
119
119
|
Content,
|
|
120
120
|
Header,
|
|
121
121
|
Title,
|