@woosmap/ui 3.117.0 → 3.120.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 +2 -2
- package/src/components/DynamicTag/DynamicTag.js +43 -19
- package/src/components/DynamicTag/DynamicTag.stories.js +47 -0
- package/src/components/DynamicTag/DynamicTag.test.js +45 -1
- package/src/components/Select/Select.js +15 -2
- package/src/icons/customers-services.svg +1 -1
- package/src/styles/console/select.styl +12 -1
- package/src/styles/website/card.styl +2 -0
- package/src/components/DynamicTag/DynalicTag.stories.js +0 -17
- package/src/images/Questionnaire Vaccination contre la Covid-19_.pdf +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@woosmap/ui",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.120.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/WebGeoServices/ui.git"
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"test:generate-output": "react-scripts test --json --outputFile=./.storybook/jest-test-results.json --silent",
|
|
34
34
|
"prestorybook:dev": "clear && echo \"DOING FIRST TEST RUN\" && CI=true npm run test:generate-output",
|
|
35
35
|
"storybook:dev": "clear && concurrently -k \"npm run storybook\" \"npm run test:generate-output\"",
|
|
36
|
-
"storybook": "start-storybook -p 9009 -s public",
|
|
36
|
+
"storybook": "start-storybook -p 9009 -s public -h localhost",
|
|
37
37
|
"build-storybook": "build-storybook -s public",
|
|
38
38
|
"icons": "svgo -f ./src/icons --config ./svgo-config.js",
|
|
39
39
|
"deploy-storybook": "storybook-to-ghpages",
|
|
@@ -5,14 +5,15 @@ import Input from '../Input/Input';
|
|
|
5
5
|
import Button from '../Button/Button';
|
|
6
6
|
import Label from '../Label/Label';
|
|
7
7
|
import { tr } from '../utils/locale';
|
|
8
|
+
import Select from '../Select/Select';
|
|
8
9
|
|
|
9
10
|
export default class DynamicTag extends Component {
|
|
10
11
|
constructor(props) {
|
|
11
12
|
super(props);
|
|
12
|
-
const { defaultTags } = props;
|
|
13
|
+
const { defaultTags, isSelector } = props;
|
|
13
14
|
this.state = {
|
|
14
15
|
inputValue: '',
|
|
15
|
-
tags: defaultTags,
|
|
16
|
+
tags: isSelector ? defaultTags.map((tag) => tag.value) : defaultTags,
|
|
16
17
|
error: null,
|
|
17
18
|
};
|
|
18
19
|
}
|
|
@@ -43,6 +44,10 @@ export default class DynamicTag extends Component {
|
|
|
43
44
|
});
|
|
44
45
|
}
|
|
45
46
|
|
|
47
|
+
handleChange = (tags) => {
|
|
48
|
+
this.setState({ tags: tags.map((tag) => tag.value) });
|
|
49
|
+
};
|
|
50
|
+
|
|
46
51
|
getTags = () => {
|
|
47
52
|
const { tags } = this.state;
|
|
48
53
|
return tags;
|
|
@@ -50,9 +55,23 @@ export default class DynamicTag extends Component {
|
|
|
50
55
|
|
|
51
56
|
renderInput = () => {
|
|
52
57
|
const { inputValue, error } = this.state;
|
|
53
|
-
const { placeholder, testId } = this.props;
|
|
58
|
+
const { placeholder, testId, isSelector, label, options, defaultTags, color } = this.props;
|
|
54
59
|
|
|
55
|
-
return (
|
|
60
|
+
return isSelector ? (
|
|
61
|
+
<Select
|
|
62
|
+
aria-label={`${testId}-select`}
|
|
63
|
+
color={color}
|
|
64
|
+
label={label}
|
|
65
|
+
isMulti
|
|
66
|
+
isCreatable
|
|
67
|
+
options={options}
|
|
68
|
+
closeMenuOnSelect={false}
|
|
69
|
+
noOptionsMessage={() => tr('No options found')}
|
|
70
|
+
placeholder={placeholder}
|
|
71
|
+
defaultValue={defaultTags}
|
|
72
|
+
onChange={this.handleChange}
|
|
73
|
+
/>
|
|
74
|
+
) : (
|
|
56
75
|
<>
|
|
57
76
|
<Input
|
|
58
77
|
placeholder={placeholder}
|
|
@@ -70,24 +89,26 @@ export default class DynamicTag extends Component {
|
|
|
70
89
|
|
|
71
90
|
render() {
|
|
72
91
|
const { tags } = this.state;
|
|
73
|
-
const { color, testId } = this.props;
|
|
92
|
+
const { color, testId, isSelector } = this.props;
|
|
74
93
|
return (
|
|
75
94
|
<div className={cl('dynamic-tag')} data-testid={testId}>
|
|
76
95
|
<div className={cl('dynamic-tag__input')}>{this.renderInput()}</div>
|
|
77
|
-
|
|
78
|
-
{
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
96
|
+
{!isSelector && (
|
|
97
|
+
<div className={cl('dynamic-tag__tags')}>
|
|
98
|
+
{tags.map((item) => (
|
|
99
|
+
<Label
|
|
100
|
+
color={color}
|
|
101
|
+
key={`label_${item}`}
|
|
102
|
+
closable
|
|
103
|
+
label={item}
|
|
104
|
+
closeCb={() => {
|
|
105
|
+
this.handleTagRemove(item);
|
|
106
|
+
}}
|
|
107
|
+
testId={`${testId}-label`}
|
|
108
|
+
/>
|
|
109
|
+
))}
|
|
110
|
+
</div>
|
|
111
|
+
)}
|
|
91
112
|
</div>
|
|
92
113
|
);
|
|
93
114
|
}
|
|
@@ -98,6 +119,7 @@ DynamicTag.defaultProps = {
|
|
|
98
119
|
placeholder: '',
|
|
99
120
|
color: '',
|
|
100
121
|
testId: 'dynamic-tag',
|
|
122
|
+
isSelector: false,
|
|
101
123
|
};
|
|
102
124
|
|
|
103
125
|
DynamicTag.propTypes = {
|
|
@@ -105,4 +127,6 @@ DynamicTag.propTypes = {
|
|
|
105
127
|
placeholder: PropTypes.string,
|
|
106
128
|
color: PropTypes.string,
|
|
107
129
|
testId: PropTypes.string,
|
|
130
|
+
isSelector: PropTypes.bool,
|
|
131
|
+
...Select.propTypes,
|
|
108
132
|
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import DynamicTag from './DynamicTag';
|
|
3
|
+
|
|
4
|
+
const Story = {
|
|
5
|
+
title: 'base/DynamicTag',
|
|
6
|
+
component: DynamicTag,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default Story;
|
|
10
|
+
|
|
11
|
+
const Template = (arg) => {
|
|
12
|
+
const { isSelector } = arg;
|
|
13
|
+
const options = [
|
|
14
|
+
{ value: 'java', label: 'Java' },
|
|
15
|
+
{ value: 'swift', label: 'Swift' },
|
|
16
|
+
{ value: 'js', label: 'Js' },
|
|
17
|
+
{
|
|
18
|
+
value: 'python',
|
|
19
|
+
label: 'Python',
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
return (
|
|
23
|
+
<div>
|
|
24
|
+
<DynamicTag
|
|
25
|
+
color="mauve"
|
|
26
|
+
defaultTags={
|
|
27
|
+
isSelector
|
|
28
|
+
? [
|
|
29
|
+
{ label: 'Js', value: 'js' },
|
|
30
|
+
{
|
|
31
|
+
label: 'Python',
|
|
32
|
+
value: 'python',
|
|
33
|
+
},
|
|
34
|
+
]
|
|
35
|
+
: ['js', 'python']
|
|
36
|
+
}
|
|
37
|
+
isSelector={isSelector}
|
|
38
|
+
isMulti
|
|
39
|
+
options={options}
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
export const Default = Template.bind({});
|
|
45
|
+
Default.args = {
|
|
46
|
+
isSelector: false,
|
|
47
|
+
};
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { render, screen, getByRole } from '@testing-library/react';
|
|
2
|
+
import { render, screen, getByRole, fireEvent } from '@testing-library/react';
|
|
3
3
|
import { act } from 'react-dom/test-utils';
|
|
4
4
|
import '@testing-library/jest-dom/extend-expect';
|
|
5
5
|
import userEvent from '@testing-library/user-event';
|
|
6
6
|
|
|
7
7
|
import DynamicTag from './DynamicTag';
|
|
8
8
|
|
|
9
|
+
const options = [
|
|
10
|
+
{ value: 'java', label: 'java' },
|
|
11
|
+
{ value: 'swift', label: 'swift' },
|
|
12
|
+
{ value: 'js', label: 'js' },
|
|
13
|
+
{
|
|
14
|
+
value: 'python',
|
|
15
|
+
label: 'python',
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
|
|
9
19
|
it('renders a DynamicTag component with default tags', () => {
|
|
10
20
|
const { container } = render(<DynamicTag defaultTags={['tag1', 'tag 2']} />);
|
|
11
21
|
expect(container.firstChild).toHaveClass('dynamic-tag');
|
|
@@ -68,3 +78,37 @@ it('cant add the same value twice', () => {
|
|
|
68
78
|
expect(screen.getByTestId('input-error')).toHaveTextContent('The value you’ve entered is already in the list');
|
|
69
79
|
expect(ref.current.getTags()).toEqual(['mytag']);
|
|
70
80
|
});
|
|
81
|
+
|
|
82
|
+
it(
|
|
83
|
+
'should render DynamicTag with Select behavior and default tags and ' +
|
|
84
|
+
'should add a new option when enter a value not present in options',
|
|
85
|
+
() => {
|
|
86
|
+
const ref = React.createRef();
|
|
87
|
+
const { container } = render(
|
|
88
|
+
<DynamicTag
|
|
89
|
+
color="mauve"
|
|
90
|
+
defaultTags={[
|
|
91
|
+
{ label: 'js', value: 'js' },
|
|
92
|
+
{
|
|
93
|
+
label: 'python',
|
|
94
|
+
value: 'python',
|
|
95
|
+
},
|
|
96
|
+
]}
|
|
97
|
+
isSelector
|
|
98
|
+
isMulti
|
|
99
|
+
options={options}
|
|
100
|
+
ref={ref}
|
|
101
|
+
/>
|
|
102
|
+
);
|
|
103
|
+
const select = screen.getByLabelText('dynamic-tag-select');
|
|
104
|
+
expect(select).toBeInTheDocument();
|
|
105
|
+
expect(ref.current.getTags()).toEqual(['js', 'python']);
|
|
106
|
+
fireEvent.change(select, { target: { value: 'c' } });
|
|
107
|
+
fireEvent.keyDown(select, { key: 'Enter', code: 'Enter', charCode: 13 });
|
|
108
|
+
expect(ref.current.getTags()).toEqual(['js', 'python', 'c']);
|
|
109
|
+
fireEvent.click(select);
|
|
110
|
+
expect(screen.getByText('java')).toBeInTheDocument();
|
|
111
|
+
expect(screen.getByText('swift')).toBeInTheDocument();
|
|
112
|
+
expect(container.querySelectorAll('div.select__item--mauve')[0]).toBeInTheDocument();
|
|
113
|
+
}
|
|
114
|
+
);
|
|
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
|
|
2
2
|
import ReactSelect from 'react-select';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import cl from 'classnames';
|
|
5
|
+
import CreatableSelect from 'react-select/creatable';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* https://react-select.com/styles#styles
|
|
@@ -9,9 +10,17 @@ import cl from 'classnames';
|
|
|
9
10
|
*/
|
|
10
11
|
export default class Select extends Component {
|
|
11
12
|
renderInput = (props) => {
|
|
12
|
-
const { error, ...rest } = props;
|
|
13
|
+
const { error, isCreatable, color, ...rest } = props;
|
|
13
14
|
|
|
14
|
-
return (
|
|
15
|
+
return isCreatable ? (
|
|
16
|
+
<CreatableSelect
|
|
17
|
+
className={cl('select__item', color ? `select__item--${color}` : null, {
|
|
18
|
+
error,
|
|
19
|
+
})}
|
|
20
|
+
classNamePrefix="select"
|
|
21
|
+
{...rest}
|
|
22
|
+
/>
|
|
23
|
+
) : (
|
|
15
24
|
<ReactSelect
|
|
16
25
|
className={cl('select__item', {
|
|
17
26
|
error,
|
|
@@ -56,6 +65,8 @@ Select.defaultProps = {
|
|
|
56
65
|
icon: null,
|
|
57
66
|
label: null,
|
|
58
67
|
error: null,
|
|
68
|
+
isCreatable: false,
|
|
69
|
+
color: undefined,
|
|
59
70
|
};
|
|
60
71
|
Select.propTypes = {
|
|
61
72
|
className: PropTypes.string,
|
|
@@ -64,4 +75,6 @@ Select.propTypes = {
|
|
|
64
75
|
error: PropTypes.string,
|
|
65
76
|
hideLabel: PropTypes.bool,
|
|
66
77
|
icon: PropTypes.string,
|
|
78
|
+
isCreatable: PropTypes.bool,
|
|
79
|
+
color: PropTypes.oneOf(['bleu', 'mauve', 'green', 'grey', 'orange', 'red', 'white', undefined, '']),
|
|
67
80
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="m77.924 62.799-16.547-7.421a1.498 1.498 0 0 0-1.824.481L50 68.885l-9.553-13.026a1.501 1.501 0 0 0-1.824-.481l-16.547 7.421a10.716 10.716 0 0 0-6.322 9.765v13.534a1.5 1.5 0 1 0 3 0V72.564a7.71 7.71 0 0 1 4.551-7.027l6.63-2.974-1.541 4.789a1.5 1.5 0 0 0 1.786 1.916l7.459-1.834 11.142 15.575c.012.017.029.029.042.045a1.57 1.57 0 0 0 .251.255c.019.015.034.033.054.047.022.016.049.021.072.036.089.057.181.103.279.139.039.015.077.031.118.043.13.036.263.06.398.061h.014c.135 0 .268-.024.398-.061.04-.011.078-.028.118-.043.097-.036.19-.083.279-.139.023-.015.049-.02.072-.036.02-.014.035-.032.054-.047.031-.025.06-.052.09-.079a1.48 1.48 0 0 0 .161-.176c.013-.016.029-.028.041-.045l11.142-15.575 7.459 1.834a1.5 1.5 0 0 0 1.786-1.916l-1.541-4.789 6.63 2.974a7.712 7.712 0 0 1 4.551 7.027v13.534a1.5 1.5 0 1 0 3 0V72.564c0-4.209-2.481-8.042-6.322-9.765Zm-9.996 2.914-5.837-1.435a1.5 1.5 0 0 0-1.578.584L50 79.559 39.487 64.862a1.5 1.5 0 0 0-1.578-.584l-5.837 1.435 1.545-4.802 5.128-2.3L48.79 72.309c.566.771 1.854.771 2.42 0l10.045-13.698 5.128 2.3 1.545 4.802Z"/><path d="M29.821 78.93a1.5 1.5 0 0 0-1.5 1.5v5.592a1.5 1.5 0 1 0 3 0V80.43a1.5 1.5 0 0 0-1.5-1.5ZM70.125 78.93a1.5 1.5 0 0 0-1.5 1.5v5.592a1.5 1.5 0 1 0 3 0V80.43a1.5 1.5 0 0 0-1.5-1.5ZM49.294 55.738c9.802 0 17.776-8.546 17.776-19.051 0-1.029-.103-2.053-.255-3.065.112-.167.191-.355.229-.557l1.324-6.97a6.578 6.578 0 0 0-3.018-6.806 48.374 48.374 0 0 0-19.654-6.811l-.25-.03a6.548 6.548 0 0 0-7.006 4.498l-1.601 4.983c-.119.371-.077.753.078 1.086-3.449 3.578-5.401 8.462-5.401 13.671 0 10.505 7.975 19.051 17.777 19.051Zm0-3c-8.148 0-14.777-7.201-14.777-16.051 0-4.616 1.805-8.907 4.953-11.955a101.76 101.76 0 0 0 24.358 9.18c.147.915.243 1.842.243 2.775 0 8.851-6.629 16.051-14.776 16.051Zm-7.998-34.875a3.566 3.566 0 0 1 3.795-2.437l.251.03a45.4 45.4 0 0 1 18.444 6.392 3.56 3.56 0 0 1 1.656 3.493c-2.464-.985-7.567-2.984-12.34-4.586a1.5 1.5 0 1 0-.955 2.844c5.108 1.714 10.611 3.894 12.739 4.752l-.498 2.623a98.773 98.773 0 0 1-24.312-9.308l1.221-3.803Z"/></svg>
|
|
@@ -67,9 +67,20 @@ select
|
|
|
67
67
|
background-color $primary15 !important
|
|
68
68
|
color $secondary !important
|
|
69
69
|
&__multi-value
|
|
70
|
+
display flex
|
|
71
|
+
align-items center
|
|
70
72
|
background-color $primary !important
|
|
71
73
|
border-radius .4rem !important
|
|
72
|
-
|
|
74
|
+
.select__item--mauve &
|
|
75
|
+
background-color $labelMauve !important
|
|
76
|
+
.select__item--green &
|
|
77
|
+
background-color $labelGreen !important
|
|
78
|
+
.select__item--grey &
|
|
79
|
+
background-color $labelGrey !important
|
|
80
|
+
.select__item--orange &
|
|
81
|
+
background-color $labelOrange !important
|
|
82
|
+
.select__item--red &
|
|
83
|
+
background-color $labelRed !important
|
|
73
84
|
&--is-disabled
|
|
74
85
|
opacity .6
|
|
75
86
|
&__label
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import DynamicTag from './DynamicTag';
|
|
3
|
-
|
|
4
|
-
const Story = {
|
|
5
|
-
title: 'base/DynamicTag',
|
|
6
|
-
component: DynamicTag,
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export default Story;
|
|
10
|
-
|
|
11
|
-
const Template = () => (
|
|
12
|
-
<div>
|
|
13
|
-
<DynamicTag color="color1" defaultTags={['js', 'python']} />
|
|
14
|
-
</div>
|
|
15
|
-
);
|
|
16
|
-
export const Default = Template.bind({});
|
|
17
|
-
Default.args = {};
|
|
Binary file
|