akeneo-design-system 0.1.182 → 0.1.185
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/lib/components/Checkbox/Checkbox.js +1 -1
- package/lib/components/Checkbox/Checkbox.js.map +1 -1
- package/lib/components/Input/TagInput/TagInput.d.ts +2 -1
- package/lib/components/Input/TagInput/TagInput.js +14 -12
- package/lib/components/Input/TagInput/TagInput.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Block/Block.unit.tsx +7 -8
- package/src/components/Checkbox/Checkbox.tsx +1 -0
- package/src/components/Input/TagInput/TagInput.stories.mdx +26 -29
- package/src/components/Input/TagInput/TagInput.tsx +31 -13
- package/src/components/Input/TagInput/TagInput.unit.tsx +58 -77
|
@@ -59,7 +59,7 @@ var checkTick = (0, styled_components_1.keyframes)(templateObject_1 || (template
|
|
|
59
59
|
var uncheckTick = (0, styled_components_1.keyframes)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n to {\n stroke-dashoffset: 27px;\n }\n"], ["\n to {\n stroke-dashoffset: 27px;\n }\n"])));
|
|
60
60
|
var Container = styled_components_1.default.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n display: flex;\n line-height: 20px;\n"], ["\n display: flex;\n line-height: 20px;\n"])));
|
|
61
61
|
var TickIcon = (0, styled_components_1.default)(icons_1.CheckIcon)(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n animation: ", " 0.2s ease-in forwards;\n opacity: 0;\n stroke-dasharray: 27px;\n stroke-dashoffset: 0;\n transition-delay: 0.2s;\n transition: opacity 0.1s ease-out;\n"], ["\n animation: ", " 0.2s ease-in forwards;\n opacity: 0;\n stroke-dasharray: 27px;\n stroke-dashoffset: 0;\n transition-delay: 0.2s;\n transition: opacity 0.1s ease-out;\n"])), uncheckTick);
|
|
62
|
-
var CheckboxContainer = styled_components_1.default.div(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n background-color: transparent;\n height: 20px;\n width: 20px;\n border: 1px solid ", ";\n border-radius: 3px;\n overflow: hidden;\n background-color: ", ";\n transition: background-color 0.2s ease-out;\n box-sizing: border-box;\n color: ", ";\n\n ", "\n\n ", "\n\n ", "\n"], ["\n background-color: transparent;\n height: 20px;\n width: 20px;\n border: 1px solid ", ";\n border-radius: 3px;\n overflow: hidden;\n background-color: ", ";\n transition: background-color 0.2s ease-out;\n box-sizing: border-box;\n color: ", ";\n\n ", "\n\n ", "\n\n ", "\n"])), (0, theme_1.getColor)('grey80'), (0, theme_1.getColor)('grey20'), (0, theme_1.getColor)('white'), function (props) {
|
|
62
|
+
var CheckboxContainer = styled_components_1.default.div(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n background-color: transparent;\n height: 20px;\n width: 20px;\n border: 1px solid ", ";\n border-radius: 3px;\n overflow: hidden;\n background-color: ", ";\n transition: background-color 0.2s ease-out;\n box-sizing: border-box;\n color: ", ";\n flex-shrink: 0;\n\n ", "\n\n ", "\n\n ", "\n"], ["\n background-color: transparent;\n height: 20px;\n width: 20px;\n border: 1px solid ", ";\n border-radius: 3px;\n overflow: hidden;\n background-color: ", ";\n transition: background-color 0.2s ease-out;\n box-sizing: border-box;\n color: ", ";\n flex-shrink: 0;\n\n ", "\n\n ", "\n\n ", "\n"])), (0, theme_1.getColor)('grey80'), (0, theme_1.getColor)('grey20'), (0, theme_1.getColor)('white'), function (props) {
|
|
63
63
|
return props.checked && (0, styled_components_1.css)(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n background-color: ", ";\n border-color: ", ";\n\n ", " {\n animation-delay: 0.2s;\n animation: ", " 0.2s ease-out forwards;\n stroke-dashoffset: 27px;\n opacity: 1;\n transition-delay: 0s;\n }\n "], ["\n background-color: ", ";\n border-color: ", ";\n\n ", " {\n animation-delay: 0.2s;\n animation: ", " 0.2s ease-out forwards;\n stroke-dashoffset: 27px;\n opacity: 1;\n transition-delay: 0s;\n }\n "])), (0, theme_1.getColor)('blue100'), (0, theme_1.getColor)('blue100'), TickIcon, checkTick);
|
|
64
64
|
}, function (props) {
|
|
65
65
|
return props.checked &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.js","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAA4D;AAC5D,qEAAyD;AACzD,qCAAqE;AACrE,qCAAwD;AACxD,qCAA+C;AAC/C,uCAA2C;AAE3C,IAAM,SAAS,OAAG,6BAAS,gHAAA,4CAI1B,IAAA,CAAC;AAEF,IAAM,WAAW,OAAG,6BAAS,mHAAA,+CAI5B,IAAA,CAAC;AAEF,IAAM,SAAS,GAAG,2BAAM,CAAC,GAAG,+GAAA,4CAG3B,IAAA,CAAC;AAEF,IAAM,QAAQ,GAAG,IAAA,2BAAM,EAAC,iBAAS,CAAC,qPAAA,iBACnB,EAAW,+JAMzB,KANc,WAAW,CAMzB,CAAC;AAEF,IAAM,iBAAiB,GAAG,2BAAM,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"Checkbox.js","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"names":[],"mappings":"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"}
|
|
@@ -3,9 +3,10 @@ import { Override } from '../../../shared';
|
|
|
3
3
|
import { InputProps } from '../common/InputProps';
|
|
4
4
|
declare type TagInputProps = Override<Override<React.InputHTMLAttributes<HTMLInputElement>, InputProps<string[]>>, {
|
|
5
5
|
value: string[];
|
|
6
|
-
onChange: (tags: string[]) => void;
|
|
7
6
|
placeholder?: string;
|
|
8
7
|
invalid?: boolean;
|
|
8
|
+
separators?: string[];
|
|
9
|
+
onChange: (tags: string[]) => void;
|
|
9
10
|
onSubmit?: () => void;
|
|
10
11
|
}>;
|
|
11
12
|
declare const TagInput: FC<TagInputProps>;
|
|
@@ -64,15 +64,15 @@ var theme_1 = require("../../../theme");
|
|
|
64
64
|
var icons_1 = require("../../../icons");
|
|
65
65
|
var shared_1 = require("../../../shared");
|
|
66
66
|
var TagInput = function (_a) {
|
|
67
|
-
var onChange = _a.onChange, placeholder = _a.placeholder, invalid = _a.invalid, _b = _a.value, value = _b === void 0 ? [] : _b, readOnly = _a.readOnly, onSubmit = _a.onSubmit, inputProps = __rest(_a, ["onChange", "placeholder", "invalid", "value", "readOnly", "onSubmit"]);
|
|
68
|
-
var
|
|
67
|
+
var onChange = _a.onChange, placeholder = _a.placeholder, invalid = _a.invalid, _b = _a.value, value = _b === void 0 ? [] : _b, readOnly = _a.readOnly, onSubmit = _a.onSubmit, _c = _a.separators, separators = _c === void 0 ? ['\\s', ',', ';'] : _c, inputProps = __rest(_a, ["onChange", "placeholder", "invalid", "value", "readOnly", "onSubmit", "separators"]);
|
|
68
|
+
var _d = (0, react_1.useState)(false), isLastTagSelected = _d[0], setLastTagAsSelected = _d[1];
|
|
69
69
|
var inputRef = (0, react_1.useRef)(null);
|
|
70
70
|
var containerRef = (0, react_1.useRef)(null);
|
|
71
71
|
var inputContainerRef = (0, react_1.useRef)(null);
|
|
72
72
|
var onChangeCreateTags = (0, react_1.useCallback)(function (event) {
|
|
73
73
|
var tagsAsString = event.currentTarget.value;
|
|
74
74
|
if (tagsAsString !== '') {
|
|
75
|
-
var newTags = tagsAsString.split(
|
|
75
|
+
var newTags = tagsAsString.split(new RegExp("[" + separators.join('') + "]+", 'g'));
|
|
76
76
|
if (newTags.length === 1) {
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
@@ -107,14 +107,15 @@ var TagInput = function (_a) {
|
|
|
107
107
|
}
|
|
108
108
|
}, [inputRef, containerRef, inputContainerRef]);
|
|
109
109
|
var handleKeyDown = (0, react_1.useCallback)(function (event) {
|
|
110
|
+
var _a, _b;
|
|
111
|
+
var inputCurrentValue = (_b = (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.value.trim()) !== null && _b !== void 0 ? _b : '';
|
|
110
112
|
if (shared_1.Key.Enter === event.key && !isLastTagSelected && !readOnly) {
|
|
111
|
-
onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit();
|
|
113
|
+
'' === inputCurrentValue ? onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit() : createTags(__spreadArray(__spreadArray([], value, true), [inputCurrentValue], false));
|
|
112
114
|
return;
|
|
113
115
|
}
|
|
114
116
|
var isDeleteKeyPressed = [shared_1.Key.Backspace.toString(), shared_1.Key.Delete.toString()].includes(event.key);
|
|
115
117
|
var tagsAreEmpty = value.length === 0;
|
|
116
|
-
|
|
117
|
-
if (!isDeleteKeyPressed || tagsAreEmpty || inputFieldIsNotEmpty) {
|
|
118
|
+
if (!isDeleteKeyPressed || tagsAreEmpty || '' !== inputCurrentValue) {
|
|
118
119
|
setLastTagAsSelected(false);
|
|
119
120
|
return;
|
|
120
121
|
}
|
|
@@ -128,7 +129,7 @@ var TagInput = function (_a) {
|
|
|
128
129
|
value.map(function (tag, index) {
|
|
129
130
|
return (react_1.default.createElement(Tag, { key: tag.toLowerCase() + "-" + index, "data-testid": "tag", isSelected: index === value.length - 1 && isLastTagSelected, readOnly: readOnly },
|
|
130
131
|
!readOnly && react_1.default.createElement(RemoveTagIcon, { onClick: function () { return removeTag(index); }, "data-testid": "remove-" + index }),
|
|
131
|
-
tag));
|
|
132
|
+
react_1.default.createElement(TagText, null, tag)));
|
|
132
133
|
}),
|
|
133
134
|
react_1.default.createElement(InputContainer, { ref: inputContainerRef, onClick: focusOnInputField },
|
|
134
135
|
react_1.default.createElement("input", __assign({ type: "text", "data-testid": "tag-input", ref: inputRef, placeholder: value.length === 0 ? placeholder : '', onKeyDown: handleKeyDown, onChange: onChangeCreateTags, onBlurCapture: onBlurCreateTag, "aria-invalid": invalid, readOnly: readOnly }, inputProps)),
|
|
@@ -136,21 +137,22 @@ var TagInput = function (_a) {
|
|
|
136
137
|
};
|
|
137
138
|
exports.TagInput = TagInput;
|
|
138
139
|
var RemoveTagIcon = (0, styled_components_1.default)(icons_1.CloseIcon)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n width: 12px;\n height: 12px;\n color: ", ";\n margin-right: 2px;\n cursor: pointer;\n"], ["\n width: 12px;\n height: 12px;\n color: ", ";\n margin-right: 2px;\n cursor: pointer;\n"])), (0, theme_1.getColor)('grey', 120));
|
|
139
|
-
var TagContainer = styled_components_1.default.ul(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n border: 1px solid ", ";\n border-radius: 2px;\n padding: 4px;\n display: flex;\n flex-wrap: wrap;\n min-height: 40px;\n gap: 5px;\n box-sizing: border-box;\n background: ", ";\n position: relative;\n width: 100%;\n\n &:focus-within {\n box-shadow: 0 0 0 2px ", ";\n }\n"], ["\n border: 1px solid ", ";\n border-radius: 2px;\n padding: 4px;\n display: flex;\n flex-wrap: wrap;\n min-height: 40px;\n gap: 5px;\n box-sizing: border-box;\n background: ", ";\n position: relative;\n width: 100%;\n\n &:focus-within {\n box-shadow: 0 0 0 2px ", ";\n }\n"])), function (_a) {
|
|
140
|
+
var TagContainer = styled_components_1.default.ul(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n border: 1px solid ", ";\n border-radius: 2px;\n padding: 4px;\n display: flex;\n flex-wrap: wrap;\n min-height: 40px;\n gap: 5px;\n box-sizing: border-box;\n background: ", ";\n position: relative;\n width: 100%;\n margin: 0;\n\n &:focus-within {\n box-shadow: 0 0 0 2px ", ";\n }\n"], ["\n border: 1px solid ", ";\n border-radius: 2px;\n padding: 4px;\n display: flex;\n flex-wrap: wrap;\n min-height: 40px;\n gap: 5px;\n box-sizing: border-box;\n background: ", ";\n position: relative;\n width: 100%;\n margin: 0;\n\n &:focus-within {\n box-shadow: 0 0 0 2px ", ";\n }\n"])), function (_a) {
|
|
140
141
|
var invalid = _a.invalid;
|
|
141
142
|
return (invalid ? (0, theme_1.getColor)('red', 100) : (0, theme_1.getColor)('grey', 80));
|
|
142
143
|
}, function (_a) {
|
|
143
144
|
var readOnly = _a.readOnly;
|
|
144
145
|
return (readOnly ? (0, theme_1.getColor)('grey', 20) : (0, theme_1.getColor)('white'));
|
|
145
146
|
}, (0, theme_1.getColor)('blue', 40));
|
|
146
|
-
var Tag = styled_components_1.default.li(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n list-style-type: none;\n padding: ", ";\n border: 1px ", " solid;\n background-color: ", ";\n display: flex;\n align-items: center;\n height: 30px;\n box-sizing: border-box;\n"], ["\n list-style-type: none;\n padding: ", ";\n border: 1px ", " solid;\n background-color: ", ";\n display: flex;\n align-items: center;\n height: 30px;\n box-sizing: border-box;\n"])), function (_a) {
|
|
147
|
+
var Tag = styled_components_1.default.li(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n list-style-type: none;\n padding: ", ";\n border: 1px ", " solid;\n background-color: ", ";\n display: flex;\n align-items: center;\n height: 30px;\n box-sizing: border-box;\n max-width: 100%;\n"], ["\n list-style-type: none;\n padding: ", ";\n border: 1px ", " solid;\n background-color: ", ";\n display: flex;\n align-items: center;\n height: 30px;\n box-sizing: border-box;\n max-width: 100%;\n"])), function (_a) {
|
|
147
148
|
var readOnly = _a.readOnly;
|
|
148
149
|
return (readOnly ? '3px 17px 3px 17px' : '3px 17px 3px 4px');
|
|
149
150
|
}, (0, theme_1.getColor)('grey', 80), function (_a) {
|
|
150
151
|
var isSelected = _a.isSelected;
|
|
151
152
|
return (isSelected ? (0, theme_1.getColor)('grey', 40) : (0, theme_1.getColor)('grey', 20));
|
|
152
153
|
});
|
|
153
|
-
var
|
|
154
|
-
var
|
|
155
|
-
var
|
|
154
|
+
var TagText = styled_components_1.default.span(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n max-width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n"], ["\n max-width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n"])));
|
|
155
|
+
var InputContainer = styled_components_1.default.li(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n list-style-type: none;\n color: ", ";\n border: 0;\n flex: 1;\n padding: 0;\n align-items: center;\n display: flex;\n\n > input {\n border: 0;\n outline: 0;\n color: ", ";\n background-color: transparent;\n width: 100%;\n\n &::placeholder {\n opacity: 1;\n color: ", ";\n font-family: ", ";\n }\n }\n"], ["\n list-style-type: none;\n color: ", ";\n border: 0;\n flex: 1;\n padding: 0;\n align-items: center;\n display: flex;\n\n > input {\n border: 0;\n outline: 0;\n color: ", ";\n background-color: transparent;\n width: 100%;\n\n &::placeholder {\n opacity: 1;\n color: ", ";\n font-family: ", ";\n }\n }\n"])), (0, theme_1.getColor)('grey', 120), (0, theme_1.getColor)('grey', 120), (0, theme_1.getColor)('grey', 100), (0, theme_1.getFontFamily)('default'));
|
|
156
|
+
var ReadOnlyIcon = (0, styled_components_1.default)(icons_1.LockIcon)(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n position: absolute;\n right: 0;\n top: 0;\n margin: 11px;\n color: ", ";\n"], ["\n position: absolute;\n right: 0;\n top: 0;\n margin: 11px;\n color: ", ";\n"])), (0, theme_1.getColor)('grey', 100));
|
|
157
|
+
var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6;
|
|
156
158
|
//# sourceMappingURL=TagInput.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TagInput.js","sourceRoot":"","sources":["../../../../src/components/Input/TagInput/TagInput.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAA2F;AAC3F,wEAAuC;AACvC,wCAA0E;AAC1E,wCAAmD;AACnD,0CAA2D;
|
|
1
|
+
{"version":3,"file":"TagInput.js","sourceRoot":"","sources":["../../../../src/components/Input/TagInput/TagInput.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {fireEvent, render, screen} from '../../storybook/test-util';
|
|
2
|
+
import {fireEvent, render, screen, act} from '../../storybook/test-util';
|
|
3
3
|
import {Block} from './Block';
|
|
4
4
|
import {IconButton} from '../IconButton/IconButton';
|
|
5
5
|
import {CloseIcon, EditIcon, PlusIcon} from '../../icons';
|
|
@@ -53,19 +53,18 @@ test('it renders actions passed by props', () => {
|
|
|
53
53
|
|
|
54
54
|
test('it supports collapsing', () => {
|
|
55
55
|
const onCollapse = jest.fn();
|
|
56
|
-
const isOpen = false;
|
|
57
56
|
jest.useFakeTimers();
|
|
58
57
|
|
|
59
58
|
render(
|
|
60
|
-
<Block title="My block" isOpen={
|
|
59
|
+
<Block title="My block" isOpen={false} onCollapse={onCollapse} collapseButtonLabel="Collapse">
|
|
61
60
|
I am a block
|
|
62
61
|
</Block>
|
|
63
62
|
);
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
act(() => {
|
|
65
|
+
fireEvent.click(screen.getByTitle('Collapse'));
|
|
66
|
+
jest.runAllTimers();
|
|
67
|
+
});
|
|
69
68
|
|
|
70
69
|
expect(onCollapse).toBeCalled();
|
|
71
70
|
expect(screen.getByText('I am a block')).toBeInTheDocument();
|
|
@@ -90,7 +89,7 @@ test('it renders children with icon', () => {
|
|
|
90
89
|
const isOpen = false;
|
|
91
90
|
|
|
92
91
|
render(
|
|
93
|
-
<Block title="My block" isOpen={isOpen} onCollapse={onCollapse} collapseButtonLabel="Collapse"
|
|
92
|
+
<Block title="My block" isOpen={isOpen} onCollapse={onCollapse} collapseButtonLabel="Collapse">
|
|
94
93
|
<PlusIcon data-testid="children-icon" />
|
|
95
94
|
Icon
|
|
96
95
|
</Block>
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import {useState} from 'react';
|
|
2
2
|
import {Meta, Story, ArgsTable, Canvas} from '@storybook/addon-docs';
|
|
3
|
+
import {action} from '@storybook/addon-actions';
|
|
3
4
|
import {TagInput} from './TagInput.tsx';
|
|
5
|
+
import {Section} from '../../../storybook/PreviewGallery';
|
|
4
6
|
|
|
5
7
|
<Meta
|
|
6
8
|
title="Components/Inputs/Tag input"
|
|
7
9
|
component={TagInput}
|
|
8
10
|
args={{
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
value: [],
|
|
12
|
+
placeholder: 'Placeholder',
|
|
13
|
+
invalid: false,
|
|
12
14
|
}}
|
|
13
15
|
/>
|
|
14
16
|
|
|
@@ -21,6 +23,7 @@ Fill an input with a list of "tags".
|
|
|
21
23
|
Tags are created when a separator is used (typed or pasted).
|
|
22
24
|
|
|
23
25
|
Tags can be separated thanks to the following characters:
|
|
26
|
+
|
|
24
27
|
- space
|
|
25
28
|
- tab
|
|
26
29
|
- line break
|
|
@@ -33,9 +36,7 @@ Tags can be separated thanks to the following characters:
|
|
|
33
36
|
<Story name="Standard">
|
|
34
37
|
{args => {
|
|
35
38
|
const [tags, setTags] = useState([]);
|
|
36
|
-
return (
|
|
37
|
-
<TagInput {...args} value={tags} onChange={setTags}/>
|
|
38
|
-
);
|
|
39
|
+
return <TagInput {...args} value={tags} onChange={setTags} onSubmit={action('submit')} />;
|
|
39
40
|
}}
|
|
40
41
|
</Story>
|
|
41
42
|
</Canvas>
|
|
@@ -47,9 +48,7 @@ Tags can be separated thanks to the following characters:
|
|
|
47
48
|
<Canvas>
|
|
48
49
|
<Story name="Existing value">
|
|
49
50
|
{args => {
|
|
50
|
-
return (
|
|
51
|
-
<TagInput value={['batman', 'superman', 'catwoman', 'joker']} onChange={() => {}}/>
|
|
52
|
-
);
|
|
51
|
+
return <TagInput value={['batman', 'superman', 'catwoman', 'joker']} onChange={() => {}} />;
|
|
53
52
|
}}
|
|
54
53
|
</Story>
|
|
55
54
|
</Canvas>
|
|
@@ -59,34 +58,32 @@ Tags can be separated thanks to the following characters:
|
|
|
59
58
|
<Canvas>
|
|
60
59
|
<Story name="With a high number of tags">
|
|
61
60
|
{args => {
|
|
62
|
-
return (
|
|
63
|
-
<TagInput value={Array.from(Array(30).keys()).map(tag => `tag-${tag}`)} onChange={() => {}}/>
|
|
64
|
-
);
|
|
61
|
+
return <TagInput value={Array.from(Array(30).keys()).map(tag => `tag-${tag}`)} onChange={() => {}} />;
|
|
65
62
|
}}
|
|
66
63
|
</Story>
|
|
67
64
|
</Canvas>
|
|
68
65
|
|
|
69
66
|
## Variation on invalid
|
|
67
|
+
|
|
70
68
|
<Canvas>
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
69
|
+
<Story name="Variation on invalid">
|
|
70
|
+
{args => {
|
|
71
|
+
return (
|
|
72
|
+
<Section>
|
|
73
|
+
<TagInput value={[]} onChange={() => {}} invalid={false} />
|
|
74
|
+
<TagInput value={[]} onChange={() => {}} invalid={true} />
|
|
75
|
+
</Section>
|
|
76
|
+
);
|
|
77
|
+
}}
|
|
78
|
+
</Story>
|
|
81
79
|
</Canvas>
|
|
82
80
|
|
|
83
81
|
## Variation on readonly
|
|
82
|
+
|
|
84
83
|
<Canvas>
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}}
|
|
91
|
-
</Story>
|
|
84
|
+
<Story name="Variation on readonly">
|
|
85
|
+
{args => {
|
|
86
|
+
return <TagInput value={['gucci', 'dior']} onChange={() => {}} readOnly={true} />;
|
|
87
|
+
}}
|
|
88
|
+
</Story>
|
|
92
89
|
</Canvas>
|
|
@@ -9,27 +9,32 @@ type TagInputProps = Override<
|
|
|
9
9
|
Override<React.InputHTMLAttributes<HTMLInputElement>, InputProps<string[]>>,
|
|
10
10
|
{
|
|
11
11
|
/**
|
|
12
|
-
* Tags to display
|
|
12
|
+
* Tags to display.
|
|
13
13
|
*/
|
|
14
14
|
value: string[];
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
17
|
+
* Placeholder displayed where there is no tag.
|
|
18
18
|
*/
|
|
19
|
-
|
|
19
|
+
placeholder?: string;
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* Defines if the input is valid on not.
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
invalid?: boolean;
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* List of separators used to create tags.
|
|
28
28
|
*/
|
|
29
|
-
|
|
29
|
+
separators?: string[];
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
32
|
+
* Handler called when tags are updated.
|
|
33
|
+
*/
|
|
34
|
+
onChange: (tags: string[]) => void;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Callback called when the user hits enter on the field.
|
|
33
38
|
*/
|
|
34
39
|
onSubmit?: () => void;
|
|
35
40
|
}
|
|
@@ -42,6 +47,7 @@ const TagInput: FC<TagInputProps> = ({
|
|
|
42
47
|
value = [],
|
|
43
48
|
readOnly,
|
|
44
49
|
onSubmit,
|
|
50
|
+
separators = ['\\s', ',', ';'], // matching spaces, tabs, line breaks, coma and semi-colon
|
|
45
51
|
...inputProps
|
|
46
52
|
}) => {
|
|
47
53
|
const [isLastTagSelected, setLastTagAsSelected] = useState<boolean>(false);
|
|
@@ -53,7 +59,7 @@ const TagInput: FC<TagInputProps> = ({
|
|
|
53
59
|
(event: ChangeEvent<HTMLInputElement>) => {
|
|
54
60
|
const tagsAsString = event.currentTarget.value;
|
|
55
61
|
if (tagsAsString !== '') {
|
|
56
|
-
const newTags = tagsAsString.split(
|
|
62
|
+
const newTags = tagsAsString.split(new RegExp(`[${separators.join('')}]+`, 'g'));
|
|
57
63
|
if (newTags.length === 1) {
|
|
58
64
|
return;
|
|
59
65
|
}
|
|
@@ -111,18 +117,20 @@ const TagInput: FC<TagInputProps> = ({
|
|
|
111
117
|
|
|
112
118
|
const handleKeyDown = useCallback(
|
|
113
119
|
(event: KeyboardEvent) => {
|
|
120
|
+
const inputCurrentValue = inputRef?.current?.value.trim() ?? '';
|
|
121
|
+
|
|
114
122
|
if (Key.Enter === event.key && !isLastTagSelected && !readOnly) {
|
|
115
|
-
onSubmit?.();
|
|
123
|
+
'' === inputCurrentValue ? onSubmit?.() : createTags([...value, ...[inputCurrentValue]]);
|
|
116
124
|
|
|
117
125
|
return;
|
|
118
126
|
}
|
|
119
127
|
|
|
120
128
|
const isDeleteKeyPressed = [Key.Backspace.toString(), Key.Delete.toString()].includes(event.key);
|
|
121
129
|
const tagsAreEmpty = value.length === 0;
|
|
122
|
-
const inputFieldIsNotEmpty = inputRef && inputRef.current && inputRef.current.value.trim() !== '';
|
|
123
130
|
|
|
124
|
-
if (!isDeleteKeyPressed || tagsAreEmpty ||
|
|
131
|
+
if (!isDeleteKeyPressed || tagsAreEmpty || '' !== inputCurrentValue) {
|
|
125
132
|
setLastTagAsSelected(false);
|
|
133
|
+
|
|
126
134
|
return;
|
|
127
135
|
}
|
|
128
136
|
|
|
@@ -153,7 +161,7 @@ const TagInput: FC<TagInputProps> = ({
|
|
|
153
161
|
readOnly={readOnly}
|
|
154
162
|
>
|
|
155
163
|
{!readOnly && <RemoveTagIcon onClick={() => removeTag(index)} data-testid={`remove-${index}`} />}
|
|
156
|
-
{tag}
|
|
164
|
+
<TagText>{tag}</TagText>
|
|
157
165
|
</Tag>
|
|
158
166
|
);
|
|
159
167
|
})}
|
|
@@ -196,6 +204,7 @@ const TagContainer = styled.ul<AkeneoThemedProps & {invalid: boolean}>`
|
|
|
196
204
|
background: ${({readOnly}) => (readOnly ? getColor('grey', 20) : getColor('white'))};
|
|
197
205
|
position: relative;
|
|
198
206
|
width: 100%;
|
|
207
|
+
margin: 0;
|
|
199
208
|
|
|
200
209
|
&:focus-within {
|
|
201
210
|
box-shadow: 0 0 0 2px ${getColor('blue', 40)};
|
|
@@ -211,6 +220,14 @@ const Tag = styled.li<AkeneoThemedProps & {isSelected: boolean; readOnly: boolea
|
|
|
211
220
|
align-items: center;
|
|
212
221
|
height: 30px;
|
|
213
222
|
box-sizing: border-box;
|
|
223
|
+
max-width: 100%;
|
|
224
|
+
`;
|
|
225
|
+
|
|
226
|
+
const TagText = styled.span`
|
|
227
|
+
max-width: 100%;
|
|
228
|
+
overflow: hidden;
|
|
229
|
+
text-overflow: ellipsis;
|
|
230
|
+
white-space: nowrap;
|
|
214
231
|
`;
|
|
215
232
|
|
|
216
233
|
const InputContainer = styled.li<AkeneoThemedProps>`
|
|
@@ -227,6 +244,7 @@ const InputContainer = styled.li<AkeneoThemedProps>`
|
|
|
227
244
|
outline: 0;
|
|
228
245
|
color: ${getColor('grey', 120)};
|
|
229
246
|
background-color: transparent;
|
|
247
|
+
width: 100%;
|
|
230
248
|
|
|
231
249
|
&::placeholder {
|
|
232
250
|
opacity: 1;
|
|
@@ -1,80 +1,58 @@
|
|
|
1
1
|
import React, {useState} from 'react';
|
|
2
2
|
import {TagInput} from './TagInput';
|
|
3
|
-
import '@testing-library/jest-dom/extend-expect';
|
|
4
3
|
import {render, screen} from '../../../storybook/test-util';
|
|
5
4
|
import userEvent from '@testing-library/user-event';
|
|
6
5
|
|
|
7
|
-
test('it renders an empty input tag', () => {
|
|
8
|
-
const TagInputContainer = () => {
|
|
9
|
-
const [tags, setTags] = useState<string[]>([]);
|
|
10
|
-
return <TagInput value={tags} onChange={setTags} />;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const result = render(<TagInputContainer />);
|
|
14
|
-
|
|
15
|
-
expect(result.container.textContent).toBe(expectedTags([]));
|
|
16
|
-
});
|
|
17
|
-
|
|
18
6
|
test('it renders a tag input with default tags', () => {
|
|
19
|
-
|
|
20
|
-
const [tags, setTags] = useState<string[]>(['gucci', 'samsung', 'apple']);
|
|
21
|
-
return <TagInput value={tags} onChange={setTags} />;
|
|
22
|
-
};
|
|
7
|
+
render(<TagInput value={['gucci', 'samsung', 'apple']} onChange={jest.fn()} />);
|
|
23
8
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
expect(
|
|
9
|
+
expect(screen.getByText('gucci')).toBeInTheDocument();
|
|
10
|
+
expect(screen.getByText('samsung')).toBeInTheDocument();
|
|
11
|
+
expect(screen.getByText('apple')).toBeInTheDocument();
|
|
27
12
|
});
|
|
28
13
|
|
|
29
14
|
test('it allows tags to be created', () => {
|
|
30
|
-
const
|
|
31
|
-
const [tags, setTags] = useState<string[]>([]);
|
|
32
|
-
return <TagInput value={tags} onChange={setTags} />;
|
|
33
|
-
};
|
|
15
|
+
const handleChange = jest.fn();
|
|
34
16
|
|
|
35
|
-
|
|
17
|
+
render(<TagInput value={[]} onChange={handleChange} />);
|
|
36
18
|
|
|
37
|
-
userEvent.type(screen.
|
|
38
|
-
|
|
19
|
+
userEvent.type(screen.getByRole('textbox'), 'gucci{space}');
|
|
20
|
+
|
|
21
|
+
expect(handleChange).toHaveBeenCalledWith(['gucci']);
|
|
39
22
|
});
|
|
40
23
|
|
|
41
|
-
test('it handles on submit callback', () => {
|
|
24
|
+
test('it can create tags using Enter and handles on submit callback', () => {
|
|
42
25
|
const handleChange = jest.fn();
|
|
43
26
|
const handleSubmit = jest.fn();
|
|
44
27
|
|
|
45
|
-
render(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
28
|
+
render(<TagInput value={['12']} onChange={handleChange} onSubmit={handleSubmit} />);
|
|
29
|
+
|
|
30
|
+
const input = screen.getByRole('textbox');
|
|
31
|
+
|
|
32
|
+
userEvent.type(input, 'nice{enter}');
|
|
33
|
+
|
|
34
|
+
expect(handleChange).toHaveBeenCalledWith(['12', 'nice']);
|
|
35
|
+
expect(handleSubmit).not.toHaveBeenCalled();
|
|
51
36
|
|
|
52
|
-
const input = screen.getByLabelText('My label');
|
|
53
|
-
userEvent.type(input, 'nice{space}');
|
|
54
37
|
userEvent.type(input, '{enter}');
|
|
55
|
-
|
|
38
|
+
|
|
56
39
|
expect(handleSubmit).toHaveBeenCalled();
|
|
57
40
|
});
|
|
58
41
|
|
|
59
|
-
test('it supports the copy
|
|
60
|
-
const
|
|
61
|
-
const [tags, setTags] = useState<string[]>([]);
|
|
62
|
-
return <TagInput value={tags} onChange={setTags} />;
|
|
63
|
-
};
|
|
42
|
+
test('it supports the copy paste of multiple tags', () => {
|
|
43
|
+
const handleChange = jest.fn();
|
|
64
44
|
|
|
65
|
-
|
|
45
|
+
render(<TagInput value={[]} onChange={handleChange} />);
|
|
66
46
|
|
|
67
|
-
userEvent.paste(screen.
|
|
68
|
-
|
|
47
|
+
userEvent.paste(screen.getByRole('textbox'), ' gucci samsung apple asus ');
|
|
48
|
+
|
|
49
|
+
expect(handleChange).toBeCalledWith(['gucci', 'samsung', 'apple', 'asus']);
|
|
69
50
|
});
|
|
70
51
|
|
|
71
52
|
test('it accepts multiple separators', () => {
|
|
72
|
-
const
|
|
73
|
-
const [tags, setTags] = useState<string[]>([]);
|
|
74
|
-
return <TagInput value={tags} onChange={setTags} />;
|
|
75
|
-
};
|
|
53
|
+
const handleChange = jest.fn();
|
|
76
54
|
|
|
77
|
-
|
|
55
|
+
render(<TagInput value={[]} onChange={handleChange} />);
|
|
78
56
|
|
|
79
57
|
/*eslint-disable */
|
|
80
58
|
const input = 'gucci samsung \
|
|
@@ -82,11 +60,22 @@ apple \
|
|
|
82
60
|
dior,renault;porsche';
|
|
83
61
|
/*eslint-enable */
|
|
84
62
|
|
|
85
|
-
userEvent.paste(screen.
|
|
86
|
-
|
|
63
|
+
userEvent.paste(screen.getByRole('textbox'), input);
|
|
64
|
+
|
|
65
|
+
expect(handleChange).toBeCalledWith(['gucci', 'samsung', 'apple', 'dior', 'renault', 'porsche']);
|
|
87
66
|
});
|
|
88
67
|
|
|
89
|
-
test('it
|
|
68
|
+
test('it can use overridden separators', () => {
|
|
69
|
+
const handleChange = jest.fn();
|
|
70
|
+
|
|
71
|
+
render(<TagInput value={[]} separators={['w', 'y']} onChange={handleChange} />);
|
|
72
|
+
|
|
73
|
+
userEvent.paste(screen.getByRole('textbox'), 'nicewsepa ratorwindeedythisyoneytoo');
|
|
74
|
+
|
|
75
|
+
expect(handleChange).toBeCalledWith(['nice', 'sepa rator', 'indeed', 'this', 'one', 'too']);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('it handles deletion of a tag using the mouse', () => {
|
|
90
79
|
const TagInputContainer = () => {
|
|
91
80
|
const [tags, setTags] = useState<string[]>([]);
|
|
92
81
|
return <TagInput value={tags} onChange={setTags} />;
|
|
@@ -94,7 +83,7 @@ test('it handle a deletion of a tag using the mouse', () => {
|
|
|
94
83
|
|
|
95
84
|
const result = render(<TagInputContainer />);
|
|
96
85
|
|
|
97
|
-
userEvent.paste(screen.
|
|
86
|
+
userEvent.paste(screen.getByRole('textbox'), 'gucci samsung apple');
|
|
98
87
|
expect(result.container.textContent).toBe(expectedTags(['gucci', 'samsung', 'apple']));
|
|
99
88
|
userEvent.click(screen.getByTestId('remove-1'));
|
|
100
89
|
expect(result.container.textContent).toBe(expectedTags(['gucci', 'apple']));
|
|
@@ -113,30 +102,27 @@ test('it supports the removal of a tag using keyboard only', () => {
|
|
|
113
102
|
const result = render(<TagInputContainer />);
|
|
114
103
|
|
|
115
104
|
expect(result.container.textContent).toBe(expectedTags(['gucci', 'samsung', 'apple']));
|
|
116
|
-
userEvent.type(screen.
|
|
105
|
+
userEvent.type(screen.getByRole('textbox'), '{backspace}');
|
|
117
106
|
expect(result.container.textContent).toBe(expectedTags(['gucci', 'samsung', 'apple']));
|
|
118
|
-
userEvent.type(screen.
|
|
107
|
+
userEvent.type(screen.getByRole('textbox'), '{del}');
|
|
119
108
|
expect(result.container.textContent).toBe(expectedTags(['gucci', 'samsung']));
|
|
120
|
-
userEvent.type(screen.
|
|
121
|
-
userEvent.type(screen.
|
|
109
|
+
userEvent.type(screen.getByRole('textbox'), '{backspace}');
|
|
110
|
+
userEvent.type(screen.getByRole('textbox'), '{backspace}');
|
|
122
111
|
expect(result.container.textContent).toBe(expectedTags(['gucci']));
|
|
123
|
-
userEvent.type(screen.
|
|
124
|
-
userEvent.type(screen.
|
|
112
|
+
userEvent.type(screen.getByRole('textbox'), '{backspace}');
|
|
113
|
+
userEvent.type(screen.getByRole('textbox'), '{backspace}');
|
|
125
114
|
expect(result.container.textContent).toBe(expectedTags([]));
|
|
126
|
-
userEvent.type(screen.
|
|
115
|
+
userEvent.type(screen.getByRole('textbox'), '{backspace}');
|
|
127
116
|
});
|
|
128
117
|
|
|
129
118
|
test('it allows input to be easily focused by clicking anywhere on the component', () => {
|
|
130
|
-
|
|
131
|
-
const [tags, setTags] = useState<string[]>([]);
|
|
132
|
-
return <TagInput value={tags} onChange={setTags} />;
|
|
133
|
-
};
|
|
119
|
+
render(<TagInput value={[]} onChange={jest.fn()} />);
|
|
134
120
|
|
|
135
|
-
|
|
121
|
+
expect(screen.getByRole('textbox')).not.toHaveFocus();
|
|
136
122
|
|
|
137
|
-
expect(screen.getByTestId('tag-input')).not.toHaveFocus();
|
|
138
123
|
userEvent.click(screen.getByTestId('tagInputContainer'));
|
|
139
|
-
|
|
124
|
+
|
|
125
|
+
expect(screen.getByRole('textbox')).toHaveFocus();
|
|
140
126
|
});
|
|
141
127
|
|
|
142
128
|
test('it creates a tag if the input loses focus', () => {
|
|
@@ -148,22 +134,17 @@ test('it creates a tag if the input loses focus', () => {
|
|
|
148
134
|
const result = render(<TagInputContainer />);
|
|
149
135
|
|
|
150
136
|
expect(result.container.textContent).toBe(expectedTags([]));
|
|
151
|
-
userEvent.type(screen.
|
|
137
|
+
userEvent.type(screen.getByRole('textbox'), 'gucci');
|
|
152
138
|
expect(result.container.textContent).toBe(expectedTags([]));
|
|
153
|
-
screen.
|
|
139
|
+
screen.getByRole('textbox').blur();
|
|
154
140
|
expect(result.container.textContent).toBe(expectedTags(['gucci']));
|
|
155
|
-
userEvent.type(screen.
|
|
156
|
-
screen.
|
|
141
|
+
userEvent.type(screen.getByRole('textbox'), 'dior');
|
|
142
|
+
screen.getByRole('textbox').blur();
|
|
157
143
|
expect(result.container.textContent).toBe(expectedTags(['gucci', 'dior']));
|
|
158
144
|
});
|
|
159
145
|
|
|
160
146
|
test('it prevents readonly tags to be deleted', () => {
|
|
161
|
-
|
|
162
|
-
const [tags, setTags] = useState<string[]>(['gucci', 'samsung', 'apple']);
|
|
163
|
-
return <TagInput value={tags} onChange={setTags} readOnly />;
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
render(<TagInputContainer />);
|
|
147
|
+
render(<TagInput value={['gucci', 'samsung', 'apple']} onChange={jest.fn()} readOnly={true} />);
|
|
167
148
|
|
|
168
149
|
expect(screen.queryByTestId('remove-0')).not.toBeInTheDocument();
|
|
169
150
|
expect(screen.queryByTestId('remove-1')).not.toBeInTheDocument();
|