@woosmap/ui 3.104.0 → 3.107.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/package.json +1 -1
- package/src/components/Demo/DistanceDemo.js +34 -4
- package/src/components/Demo/DistanceDemo.test.js +9 -2
- package/src/components/Demo/SkeletonDemo.js +6 -10
- package/src/components/Panel/Panel.js +50 -4
- package/src/components/Panel/Panel.stories.js +37 -3
- package/src/components/Panel/Panel.styl +43 -0
- package/src/components/Panel/Panel.test.js +16 -0
package/package.json
CHANGED
|
@@ -37,6 +37,12 @@ const units = [
|
|
|
37
37
|
{ value: 'metric', label: 'Metric' },
|
|
38
38
|
{ value: 'imperial', label: 'Imperial' },
|
|
39
39
|
];
|
|
40
|
+
|
|
41
|
+
const methods = [
|
|
42
|
+
{ value: 'distance', label: 'Shortest' },
|
|
43
|
+
{ value: 'time', label: 'Fastest' },
|
|
44
|
+
];
|
|
45
|
+
|
|
40
46
|
export default class DistanceDemo extends Component {
|
|
41
47
|
constructor(props) {
|
|
42
48
|
super(props);
|
|
@@ -60,6 +66,7 @@ export default class DistanceDemo extends Component {
|
|
|
60
66
|
originLocation: this.defaultOrigin.location,
|
|
61
67
|
destinationLocation: this.defaultDestination.location,
|
|
62
68
|
unit: units[0],
|
|
69
|
+
method: methods[0],
|
|
63
70
|
travelMode: travelModes[0],
|
|
64
71
|
language: (defaultLang || languages[1]).value,
|
|
65
72
|
alternatives: false,
|
|
@@ -161,12 +168,14 @@ export default class DistanceDemo extends Component {
|
|
|
161
168
|
})
|
|
162
169
|
.catch((error) => {
|
|
163
170
|
const errorResult = error?.data?.error_message ?? 'Unhandled error';
|
|
164
|
-
this.
|
|
171
|
+
if (this.mounted) {
|
|
172
|
+
this.setState({ error: errorResult });
|
|
173
|
+
}
|
|
165
174
|
});
|
|
166
175
|
};
|
|
167
176
|
|
|
168
177
|
getRequestparams = () => {
|
|
169
|
-
const { language, originLocation, destinationLocation, unit, travelMode, alternatives } = this.state;
|
|
178
|
+
const { language, originLocation, destinationLocation, unit, method, travelMode, alternatives } = this.state;
|
|
170
179
|
|
|
171
180
|
return {
|
|
172
181
|
key: Constants.woosmapKey,
|
|
@@ -174,6 +183,7 @@ export default class DistanceDemo extends Component {
|
|
|
174
183
|
destination: `${destinationLocation.lat},${destinationLocation.lng}`,
|
|
175
184
|
language,
|
|
176
185
|
units: unit.value,
|
|
186
|
+
method: method.value,
|
|
177
187
|
mode: travelMode.value,
|
|
178
188
|
alternatives,
|
|
179
189
|
};
|
|
@@ -264,7 +274,7 @@ export default class DistanceDemo extends Component {
|
|
|
264
274
|
};
|
|
265
275
|
|
|
266
276
|
renderFooterFilters = () => {
|
|
267
|
-
const { unit, travelMode, language, alternatives } = this.state;
|
|
277
|
+
const { unit, method, travelMode, language, alternatives } = this.state;
|
|
268
278
|
|
|
269
279
|
const filterTravelMode = {
|
|
270
280
|
key: 'travelmode',
|
|
@@ -304,7 +314,26 @@ export default class DistanceDemo extends Component {
|
|
|
304
314
|
),
|
|
305
315
|
};
|
|
306
316
|
|
|
317
|
+
const filterMethod = {
|
|
318
|
+
key: 'method',
|
|
319
|
+
component: (
|
|
320
|
+
<ButtonGroup isLight>
|
|
321
|
+
{methods.map((item) => (
|
|
322
|
+
<Button
|
|
323
|
+
type="group"
|
|
324
|
+
size="small"
|
|
325
|
+
key={item.value}
|
|
326
|
+
label={item.label}
|
|
327
|
+
active={item === method}
|
|
328
|
+
onClick={() => this.setState({ method: item }, this.requestDistance)}
|
|
329
|
+
/>
|
|
330
|
+
))}
|
|
331
|
+
</ButtonGroup>
|
|
332
|
+
),
|
|
333
|
+
};
|
|
334
|
+
|
|
307
335
|
const filterLanguage = {
|
|
336
|
+
key: 'language',
|
|
308
337
|
label: tr('Language'),
|
|
309
338
|
component: (
|
|
310
339
|
<ButtonGroup className="language" isLight>
|
|
@@ -326,6 +355,7 @@ export default class DistanceDemo extends Component {
|
|
|
326
355
|
};
|
|
327
356
|
|
|
328
357
|
const filterAlternatives = {
|
|
358
|
+
key: 'alternatives',
|
|
329
359
|
label: '',
|
|
330
360
|
component: (
|
|
331
361
|
<Input
|
|
@@ -339,7 +369,7 @@ export default class DistanceDemo extends Component {
|
|
|
339
369
|
),
|
|
340
370
|
};
|
|
341
371
|
|
|
342
|
-
return [filterAlternatives, filterTravelMode,
|
|
372
|
+
return [filterAlternatives, filterTravelMode, filterMethod, filterLanguage, filterUnit];
|
|
343
373
|
};
|
|
344
374
|
|
|
345
375
|
render() {
|
|
@@ -23,6 +23,13 @@ it('test metrics button', () => {
|
|
|
23
23
|
expect(screen.getByText('units=imperial&\\')).toBeVisible();
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
+
it('test method button', () => {
|
|
27
|
+
render(<DistanceDemo />);
|
|
28
|
+
expect(screen.getByText('method=distance&\\')).toBeVisible();
|
|
29
|
+
fireEvent.click(screen.getByLabelText('Fastest'));
|
|
30
|
+
expect(screen.getByText('method=time&\\')).toBeVisible();
|
|
31
|
+
});
|
|
32
|
+
|
|
26
33
|
it('test language button', () => {
|
|
27
34
|
render(<DistanceDemo />);
|
|
28
35
|
expect(screen.getByText('language=gb&\\')).toBeVisible();
|
|
@@ -33,11 +40,11 @@ it('test language button', () => {
|
|
|
33
40
|
it('test alternative route checkbox', () => {
|
|
34
41
|
render(<DistanceDemo />);
|
|
35
42
|
expect(screen.getByText('alternatives=false"')).toBeVisible();
|
|
36
|
-
|
|
37
|
-
const checkbox = screen.getByText('Alternative routes').parentElement.querySelectorAll('input')[0];
|
|
43
|
+
const [checkbox] = screen.getByText('Alternative routes').parentElement.querySelectorAll('input');
|
|
38
44
|
fireEvent.click(checkbox);
|
|
39
45
|
expect(screen.getByText('alternatives=true"')).toBeVisible();
|
|
40
46
|
});
|
|
47
|
+
|
|
41
48
|
it('catches 200 with error', async () => {
|
|
42
49
|
const backup = axios.create;
|
|
43
50
|
axios.create = () => ({
|
|
@@ -147,16 +147,12 @@ export default class SkeletonDemo extends Component {
|
|
|
147
147
|
if (!footerFilters || footerFilters.length === 0) {
|
|
148
148
|
return null;
|
|
149
149
|
}
|
|
150
|
-
return (
|
|
151
|
-
|
|
152
|
-
{
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
</div>
|
|
157
|
-
))}
|
|
158
|
-
</>
|
|
159
|
-
);
|
|
150
|
+
return footerFilters.map((filter) => (
|
|
151
|
+
<div className="demo__input-container" key={filter.label || filter.key}>
|
|
152
|
+
{filter.label ? <p className="demo__label demo__label--filter">{filter.label}</p> : false}
|
|
153
|
+
{filter.component}
|
|
154
|
+
</div>
|
|
155
|
+
));
|
|
160
156
|
};
|
|
161
157
|
|
|
162
158
|
render() {
|
|
@@ -8,7 +8,7 @@ import withClickOutside from '../withClickOutside/withClickOutside';
|
|
|
8
8
|
class Panel extends Component {
|
|
9
9
|
constructor(props) {
|
|
10
10
|
super(props);
|
|
11
|
-
this.state = { open: false };
|
|
11
|
+
this.state = { open: false, fakeValues: [] };
|
|
12
12
|
this.clickOutsideRef = React.createRef();
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -23,7 +23,25 @@ class Panel extends Component {
|
|
|
23
23
|
this.close();
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
setFakeValues = () => {
|
|
27
|
+
const { numberOfPlaceholderSections } = this.props;
|
|
28
|
+
this.setState({
|
|
29
|
+
fakeValues: Array(numberOfPlaceholderSections)
|
|
30
|
+
.fill(null)
|
|
31
|
+
.map((_, containerIndex) =>
|
|
32
|
+
Array(2)
|
|
33
|
+
.fill(null)
|
|
34
|
+
.map((__, lineIndex) => ({
|
|
35
|
+
width: Math.floor(Math.random() * (10 - 90) + 90),
|
|
36
|
+
containerIndex,
|
|
37
|
+
lineIndex,
|
|
38
|
+
}))
|
|
39
|
+
),
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
|
|
26
43
|
open = () => {
|
|
44
|
+
this.setFakeValues();
|
|
27
45
|
this.setState({ open: true });
|
|
28
46
|
};
|
|
29
47
|
|
|
@@ -48,9 +66,30 @@ class Panel extends Component {
|
|
|
48
66
|
}
|
|
49
67
|
};
|
|
50
68
|
|
|
69
|
+
getPlaceholderSections = () => {
|
|
70
|
+
const { fakeValues } = this.state;
|
|
71
|
+
return (
|
|
72
|
+
<div className="panel__body__fake-content">
|
|
73
|
+
{fakeValues.map((section) => (
|
|
74
|
+
<div className="panel__body__fake-content__section" key={`section-${section[0].containerIndex}`}>
|
|
75
|
+
{section.map(({ width, containerIndex, lineIndex }) => (
|
|
76
|
+
<div
|
|
77
|
+
className="panel__fake-line"
|
|
78
|
+
key={`section-${containerIndex}-${lineIndex}`}
|
|
79
|
+
style={{ width: `${width}%` }}
|
|
80
|
+
/>
|
|
81
|
+
))}
|
|
82
|
+
</div>
|
|
83
|
+
))}
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
getPlaceholderHeader = () => <span className="panel__header__fake-action" />;
|
|
89
|
+
|
|
51
90
|
render() {
|
|
52
91
|
const { open } = this.state;
|
|
53
|
-
const {
|
|
92
|
+
const { position, header, disableCloseOutside, loading, testId, children, ...rest } = this.props;
|
|
54
93
|
return (
|
|
55
94
|
<AnimatePresence>
|
|
56
95
|
{open && (
|
|
@@ -69,7 +108,10 @@ class Panel extends Component {
|
|
|
69
108
|
{...rest}
|
|
70
109
|
>
|
|
71
110
|
<div className="panel__header">
|
|
72
|
-
{
|
|
111
|
+
{loading
|
|
112
|
+
? this.getPlaceholderHeader()
|
|
113
|
+
: header && <div className="panel__header__content">{header}</div>}
|
|
114
|
+
|
|
73
115
|
<div className="panel__header__action">
|
|
74
116
|
<Button
|
|
75
117
|
className={cl('panel__header__action__btn')}
|
|
@@ -80,7 +122,7 @@ class Panel extends Component {
|
|
|
80
122
|
/>
|
|
81
123
|
</div>
|
|
82
124
|
</div>
|
|
83
|
-
<div className="panel__body">{children}</div>
|
|
125
|
+
<div className="panel__body">{loading ? this.getPlaceholderSections() : children}</div>
|
|
84
126
|
</motion.div>
|
|
85
127
|
)}
|
|
86
128
|
</AnimatePresence>
|
|
@@ -95,6 +137,8 @@ Panel.defaultProps = {
|
|
|
95
137
|
header: null,
|
|
96
138
|
disableCloseOutside: false,
|
|
97
139
|
testId: 'panel',
|
|
140
|
+
loading: false,
|
|
141
|
+
numberOfPlaceholderSections: 6,
|
|
98
142
|
};
|
|
99
143
|
|
|
100
144
|
Panel.propTypes = {
|
|
@@ -105,6 +149,8 @@ Panel.propTypes = {
|
|
|
105
149
|
children: PropTypes.node.isRequired,
|
|
106
150
|
position: PropTypes.oneOf(['right', 'left']),
|
|
107
151
|
header: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
152
|
+
loading: PropTypes.bool,
|
|
153
|
+
numberOfPlaceholderSections: PropTypes.number,
|
|
108
154
|
};
|
|
109
155
|
|
|
110
156
|
export default withClickOutside(Panel, '.ignore-click-outside-panel');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useRef, useState } from 'react';
|
|
2
2
|
import Panel from './Panel';
|
|
3
3
|
import Button from '../Button/Button';
|
|
4
4
|
|
|
@@ -10,11 +10,45 @@ const Story = {
|
|
|
10
10
|
export default Story;
|
|
11
11
|
|
|
12
12
|
const Template = () => {
|
|
13
|
-
const
|
|
13
|
+
const [loading, setLoading] = useState(false);
|
|
14
|
+
const panelRef = useRef(null);
|
|
15
|
+
const loadingPanelRef = useRef(null);
|
|
16
|
+
|
|
17
|
+
const openLoadingPanel = () => {
|
|
18
|
+
setLoading(true);
|
|
19
|
+
loadingPanelRef.current.toggle();
|
|
20
|
+
setTimeout(() => setLoading(false), 3000);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const getHeader = () => <Button icon="settings" />;
|
|
24
|
+
|
|
14
25
|
return (
|
|
15
26
|
<div>
|
|
16
|
-
<
|
|
27
|
+
<div>
|
|
28
|
+
<Button onClick={() => panelRef.current.toggle()} label="Toggle panel" />
|
|
29
|
+
</div>
|
|
30
|
+
<div>
|
|
31
|
+
<Button onClick={openLoadingPanel} label="Toggle loading panel" />
|
|
32
|
+
</div>
|
|
17
33
|
<Panel ref={panelRef}>My panel</Panel>
|
|
34
|
+
<Panel ref={loadingPanelRef} loading={loading} header={getHeader()}>
|
|
35
|
+
<div>
|
|
36
|
+
<div>some info 1</div>
|
|
37
|
+
<div>some sub info 1</div>
|
|
38
|
+
</div>
|
|
39
|
+
<div>
|
|
40
|
+
<div>some info 2</div>
|
|
41
|
+
<div>some sub info 2</div>
|
|
42
|
+
</div>
|
|
43
|
+
<div>
|
|
44
|
+
<div>some info 3</div>
|
|
45
|
+
<div>some sub info 3</div>
|
|
46
|
+
</div>
|
|
47
|
+
<div>
|
|
48
|
+
<div>some info 3</div>
|
|
49
|
+
<div>some sub info 3</div>
|
|
50
|
+
</div>
|
|
51
|
+
</Panel>
|
|
18
52
|
</div>
|
|
19
53
|
);
|
|
20
54
|
};
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
@keyframes gradient
|
|
2
|
+
0%
|
|
3
|
+
background-position 80% 0%
|
|
4
|
+
100%
|
|
5
|
+
background-position -20% 0%
|
|
1
6
|
.panel
|
|
2
7
|
position absolute
|
|
3
8
|
z-index 10
|
|
@@ -44,6 +49,13 @@
|
|
|
44
49
|
fullw()
|
|
45
50
|
display flex
|
|
46
51
|
align-items center
|
|
52
|
+
&__fake-action
|
|
53
|
+
sq()
|
|
54
|
+
br(50)
|
|
55
|
+
background $dark20
|
|
56
|
+
background linear-gradient(90deg, $dark20 20%, $dark30 30%, $dark20 40%)
|
|
57
|
+
background-size 400% 400%
|
|
58
|
+
animation gradient 1.4s ease-in-out infinite
|
|
47
59
|
&__body
|
|
48
60
|
fullh()
|
|
49
61
|
mbib(4)
|
|
@@ -88,6 +100,37 @@
|
|
|
88
100
|
top - .2rem
|
|
89
101
|
content "\2022"
|
|
90
102
|
color $secondary-medium60
|
|
103
|
+
&__fake-content
|
|
104
|
+
padding 2rem
|
|
105
|
+
width 100%
|
|
106
|
+
&__section
|
|
107
|
+
mbib(1)
|
|
108
|
+
width 100%
|
|
109
|
+
margin-bottom 4rem
|
|
110
|
+
&:first-child
|
|
111
|
+
.panel__fake-line
|
|
112
|
+
&:first-child
|
|
113
|
+
height 2rem
|
|
114
|
+
background $dark20
|
|
115
|
+
background linear-gradient(90deg, $dark20 20%, $dark30 30%, $dark20 40%)
|
|
116
|
+
background-size 400% 400%
|
|
117
|
+
animation gradient 1.4s ease-in-out infinite
|
|
118
|
+
&:last-child
|
|
119
|
+
height 1rem
|
|
120
|
+
&__fake-line
|
|
121
|
+
br(10)
|
|
122
|
+
background $dark6
|
|
123
|
+
background linear-gradient(90deg, $dark6 20%, $dark10 30%, $dark6 40%)
|
|
124
|
+
background-size 400% 400%
|
|
125
|
+
animation gradient 1.4s ease-in-out infinite
|
|
126
|
+
height 1rem
|
|
127
|
+
&:nth-child(even)
|
|
128
|
+
background $dark6
|
|
129
|
+
background linear-gradient(90deg, $dark10 20%, $dark20 30%, $dark10 40%)
|
|
130
|
+
background-size 400% 400%
|
|
131
|
+
animation gradient 1.4s ease-in-out infinite
|
|
132
|
+
height 1.2rem
|
|
133
|
+
|
|
91
134
|
@media screen and (max-width 720px)
|
|
92
135
|
.panel
|
|
93
136
|
width 100%
|
|
@@ -35,3 +35,19 @@ it('is hidden after clicking close', () => {
|
|
|
35
35
|
// nothink
|
|
36
36
|
}
|
|
37
37
|
});
|
|
38
|
+
|
|
39
|
+
it('opens on placeholder if loading prop is passed down and with provided num of placeholder sections', () => {
|
|
40
|
+
const panelRef = React.createRef();
|
|
41
|
+
const { container } = render(
|
|
42
|
+
<Panel ref={panelRef} loading numberOfPlaceholderSections={4}>
|
|
43
|
+
content
|
|
44
|
+
</Panel>
|
|
45
|
+
);
|
|
46
|
+
act(() => {
|
|
47
|
+
panelRef.current.open();
|
|
48
|
+
});
|
|
49
|
+
expect(screen.queryByText('content')).not.toBeInTheDocument();
|
|
50
|
+
expect(container.querySelector('.panel__body__fake-content')).toBeInTheDocument();
|
|
51
|
+
expect(container.querySelectorAll('.panel__body__fake-content__section').length).toBe(4);
|
|
52
|
+
expect(container.querySelectorAll('.panel__fake-line').length).toBe(8);
|
|
53
|
+
});
|