@ftdata/ui 0.0.8 → 0.0.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/dist/assets/fonts/Inter-Italic.js +2 -0
- package/dist/assets/fonts/Inter.js +2 -0
- package/dist/components/DoubleList/DoubleList.stories.d.ts +2 -2
- package/dist/components/DoubleList/DoubleList.stories.js +43 -43
- package/dist/components/DoubleList/Row/index.d.ts +4 -0
- package/dist/components/DoubleList/Row/index.js +12 -0
- package/dist/components/DoubleList/Row/style.d.ts +1 -0
- package/dist/components/DoubleList/Row/style.js +31 -0
- package/dist/components/DoubleList/index.js +27 -35
- package/dist/components/DoubleList/style.d.ts +0 -1
- package/dist/components/DoubleList/style.js +2 -31
- package/dist/components/Menu/Menu.stories.d.ts +6 -0
- package/dist/components/Menu/Menu.stories.js +116 -0
- package/dist/components/Menu/index.js +29 -14
- package/dist/components/Menu/styles.d.ts +1 -0
- package/dist/components/Menu/styles.js +44 -28
- package/dist/components/MultiSelect/MultiSelectList/Row/index.d.ts +7 -0
- package/dist/components/MultiSelect/MultiSelectList/Row/index.js +26 -0
- package/dist/components/MultiSelect/MultiSelectList/Row/style.d.ts +6 -0
- package/dist/components/MultiSelect/MultiSelectList/Row/style.js +48 -0
- package/dist/components/MultiSelect/MultiSelectList/index.d.ts +4 -3
- package/dist/components/MultiSelect/MultiSelectList/index.js +51 -41
- package/dist/components/MultiSelect/MultiSelectList/style.d.ts +0 -1
- package/dist/components/MultiSelect/MultiSelectList/style.js +2 -31
- package/dist/components/MultiSelect/helpers/addOption.d.ts +5 -0
- package/dist/components/MultiSelect/helpers/addOption.js +14 -0
- package/dist/components/MultiSelect/helpers/computeUnselected.d.ts +2 -0
- package/dist/components/MultiSelect/helpers/computeUnselected.js +2 -0
- package/dist/components/MultiSelect/helpers/feedbackText.d.ts +5 -0
- package/dist/components/MultiSelect/helpers/feedbackText.js +30 -0
- package/dist/components/MultiSelect/helpers/filterOptions.d.ts +2 -0
- package/dist/components/MultiSelect/helpers/filterOptions.js +5 -0
- package/dist/components/MultiSelect/helpers/removeOptions.d.ts +5 -0
- package/dist/components/MultiSelect/helpers/removeOptions.js +9 -0
- package/dist/components/MultiSelect/index.d.ts +29 -14
- package/dist/components/MultiSelect/index.js +149 -215
- package/dist/components/MultiSelect/styles.d.ts +6 -5
- package/dist/components/MultiSelect/styles.js +20 -66
- package/dist/components/Select/List/Row/index.d.ts +11 -0
- package/dist/components/Select/List/Row/index.js +29 -0
- package/dist/components/{CustomSelect/CustomSelectList → Select/List/Row}/style.d.ts +0 -2
- package/dist/components/{CustomSelect/CustomSelectList → Select/List/Row}/style.js +1 -54
- package/dist/components/Select/List/index.d.ts +12 -0
- package/dist/components/Select/List/index.js +63 -0
- package/dist/components/Select/List/style.d.ts +2 -0
- package/dist/components/Select/List/style.js +56 -0
- package/dist/components/Select/index.d.ts +34 -0
- package/dist/components/{CustomSelect → Select}/index.js +11 -9
- package/dist/components/{CustomSelect → Select}/styles.d.ts +2 -2
- package/dist/components/{CustomSelect → Select}/styles.js +6 -8
- package/dist/components/fields/components/HelpText/index.d.ts +8 -0
- package/dist/components/fields/components/HelpText/index.js +35 -0
- package/dist/components/fields/components/HelpText/modifiers/colors.d.ts +4 -0
- package/dist/components/fields/components/HelpText/modifiers/colors.js +9 -0
- package/dist/components/fields/components/HelpText/styles.d.ts +2 -0
- package/dist/components/fields/components/HelpText/styles.js +19 -0
- package/dist/components/fields/components/Label/index.d.ts +8 -0
- package/dist/components/fields/components/Label/index.js +22 -0
- package/dist/components/fields/components/Label/styles.d.ts +5 -0
- package/dist/components/fields/components/Label/styles.js +28 -0
- package/dist/components/fields/components/RotateButton/index.d.ts +6 -0
- package/dist/components/fields/components/RotateButton/index.js +13 -0
- package/dist/components/fields/components/RotateButton/styles.d.ts +5 -0
- package/dist/components/fields/components/RotateButton/styles.js +10 -0
- package/dist/components/fields/helpers/getFeedbackType.d.ts +2 -0
- package/dist/components/fields/helpers/getFeedbackType.js +11 -0
- package/dist/components/fields/modifiers/color_modifiers.d.ts +2 -0
- package/dist/components/fields/modifiers/color_modifiers.js +7 -0
- package/dist/components/fields/modifiers/inputColorModifier.d.ts +2 -0
- package/dist/components/fields/modifiers/inputColorModifier.js +14 -0
- package/dist/components/fields/modifiers/selectColorModifier.d.ts +2 -0
- package/dist/components/fields/modifiers/selectColorModifier.js +10 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/static/font/Inter-Italic.ttf +0 -0
- package/dist/static/font/Inter.ttf +0 -0
- package/dist/style/base.css +11 -4
- package/dist/types/feedback.d.ts +1 -0
- package/package.json +2 -2
- package/dist/assets/fonts/Inter-Regular.js +0 -2
- package/dist/components/CustomSelect/CustomSelect.stories.d.ts +0 -73
- package/dist/components/CustomSelect/CustomSelect.stories.js +0 -477
- package/dist/components/CustomSelect/CustomSelectList/index.d.ts +0 -10
- package/dist/components/CustomSelect/CustomSelectList/index.js +0 -66
- package/dist/components/CustomSelect/index.d.ts +0 -30
- package/dist/components/MultiSelect/MultiSelect.stories.d.ts +0 -61
- package/dist/components/MultiSelect/MultiSelect.stories.js +0 -336
- package/dist/static/font/Inter-Regular.ttf +0 -0
- /package/dist/components/MultiSelect/{calcTextSize.d.ts → helpers/calcTextSize.d.ts} +0 -0
- /package/dist/components/MultiSelect/{calcTextSize.js → helpers/calcTextSize.js} +0 -0
|
@@ -1,282 +1,216 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useEffect, useRef, useState } from "react";
|
|
3
|
-
import { BadgesContainer,
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import calcTextSize from "./calcTextSize.js";
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { BadgesContainer, LabelContainer, MaxItemsIndicator, MultiSelectContainer, MultiSelectWrapper, ResizableInput } from "./styles.js";
|
|
4
|
+
import Label from "../fields/components/Label/index.js";
|
|
5
|
+
import { getHelpTextFeedbackType } from "../fields/helpers/getFeedbackType.js";
|
|
7
6
|
import { Icon } from "@ftdata/f-icons";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
import HelpText from "../fields/components/HelpText/index.js";
|
|
8
|
+
import MultiSelectList from "./MultiSelectList/index.js";
|
|
9
|
+
import Badge from "./Badge/index.js";
|
|
10
|
+
import { addOption } from "./helpers/addOption.js";
|
|
11
|
+
import { removeOption } from "./helpers/removeOptions.js";
|
|
12
|
+
import { computeUnselected } from "./helpers/computeUnselected.js";
|
|
13
|
+
import { filterOptions } from "./helpers/filterOptions.js";
|
|
14
|
+
import { feedbackText } from "./helpers/feedbackText.js";
|
|
15
|
+
import { COLOR_NEUTRAL_DARK } from "@ftdata/f-tokens";
|
|
16
|
+
import RotateButton from "../fields/components/RotateButton/index.js";
|
|
17
|
+
import calcTextSize from "./helpers/calcTextSize.js";
|
|
18
|
+
function MultiSelect({ helpText, label, sublabel, required, disabled, feedback, helpIcon, name, translation, state, updateState, placeholder, max, loading, actions, selectAll, total, icon, onLoadMore }) {
|
|
12
19
|
const [showList, setShowList] = useState(false);
|
|
13
|
-
const [
|
|
20
|
+
const [query, setQuery] = useState("");
|
|
14
21
|
const [inputSize, setInputSize] = useState(0);
|
|
15
|
-
const [isFocused, setIsFocused] = useState(false);
|
|
16
|
-
const prevOptionsRef = useRef([]);
|
|
17
|
-
const valueRef = useRef([]);
|
|
18
22
|
const inputRef = useRef(null);
|
|
19
23
|
const containerRef = useRef(null);
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
value: "",
|
|
26
|
-
label: translation("all_were_selected")
|
|
27
|
-
};
|
|
28
|
-
const maxLimit = {
|
|
29
|
-
value: "",
|
|
30
|
-
label: translation("the_selection_limit_has_been_reached")
|
|
31
|
-
};
|
|
32
|
-
const empty = {
|
|
33
|
-
value: "",
|
|
34
|
-
label: translation("no_data_is_available")
|
|
35
|
-
};
|
|
36
|
-
const computedOptions = ()=>{
|
|
37
|
-
if (0 === options.length) return [
|
|
38
|
-
empty
|
|
39
|
-
];
|
|
40
|
-
if (maxItems && maxItems > 0 && maxItems === selected.length) return [
|
|
41
|
-
maxLimit
|
|
42
|
-
];
|
|
43
|
-
if ("" !== inputValue) return filtered;
|
|
44
|
-
if (unselected.length > 0) return unselected;
|
|
45
|
-
return [
|
|
46
|
-
allSelected
|
|
47
|
-
];
|
|
48
|
-
};
|
|
49
|
-
const removeSelected = (value)=>{
|
|
50
|
-
const newSelected = selected.filter((option)=>option.value !== value);
|
|
51
|
-
setSelected(newSelected);
|
|
52
|
-
inputRef.current?.focus();
|
|
53
|
-
setIsFocused(true);
|
|
54
|
-
};
|
|
55
|
-
const addSelected = (event, option)=>{
|
|
56
|
-
event.stopPropagation();
|
|
57
|
-
if (maxItems && selected.length === maxItems) return void setUnselected([]);
|
|
58
|
-
if (0 === unselected.length) return;
|
|
59
|
-
setFiltered([]);
|
|
60
|
-
setInputValue("");
|
|
61
|
-
setSelected((prev)=>[
|
|
62
|
-
...prev,
|
|
63
|
-
option
|
|
64
|
-
]);
|
|
65
|
-
inputRef.current?.focus();
|
|
66
|
-
setIsFocused(true);
|
|
67
|
-
};
|
|
68
|
-
const addSelectedByEnter = (option)=>{
|
|
69
|
-
if (maxItems && selected.length === maxItems) return void setUnselected([]);
|
|
70
|
-
if (0 === unselected.length) return;
|
|
71
|
-
setFiltered([]);
|
|
72
|
-
setInputValue("");
|
|
24
|
+
const { selected, options, filtered, unselected } = state;
|
|
25
|
+
const handleAddOption = (option)=>{
|
|
26
|
+
const result = addOption(selected, options, option, max);
|
|
27
|
+
if (!result) return;
|
|
28
|
+
setQuery("");
|
|
73
29
|
setInputSize(1);
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
30
|
+
updateState({
|
|
31
|
+
...result,
|
|
32
|
+
filtered: []
|
|
33
|
+
});
|
|
78
34
|
inputRef.current?.focus();
|
|
79
|
-
setIsFocused(true);
|
|
80
|
-
};
|
|
81
|
-
const toggleList = ()=>{
|
|
82
|
-
if (!inputRef.current) {
|
|
83
|
-
setShowList(false);
|
|
84
|
-
setIsFocused(false);
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
if (showList) {
|
|
88
|
-
setShowList(false);
|
|
89
|
-
inputRef.current.blur();
|
|
90
|
-
setIsFocused(false);
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
setShowList(true);
|
|
94
|
-
inputRef.current.focus();
|
|
95
|
-
setIsFocused(true);
|
|
96
|
-
};
|
|
97
|
-
const handleClickOutside = (event)=>{
|
|
98
|
-
if (containerRef.current && containerRef.current.contains(event.target)) return;
|
|
99
|
-
setShowList(false);
|
|
100
|
-
setIsFocused(false);
|
|
101
35
|
};
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return labelNormalized.includes(valueNormalized);
|
|
36
|
+
const handleRemoveOption = (option)=>{
|
|
37
|
+
const result = removeOption(selected, options, option);
|
|
38
|
+
updateState({
|
|
39
|
+
...result,
|
|
40
|
+
filtered: []
|
|
108
41
|
});
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
]);
|
|
42
|
+
};
|
|
43
|
+
const removeLast = ()=>{
|
|
44
|
+
if (!selected.length || query) return;
|
|
45
|
+
handleRemoveOption(selected[selected.length - 1]);
|
|
113
46
|
};
|
|
114
47
|
const handleChange = (event)=>{
|
|
115
|
-
|
|
48
|
+
const value = event.target.value;
|
|
49
|
+
setQuery(value);
|
|
116
50
|
const textStyle = "500 14px Inter";
|
|
117
|
-
const newInputSize = calcTextSize(
|
|
51
|
+
const newInputSize = calcTextSize(value, textStyle, "rem");
|
|
118
52
|
if (newInputSize) setInputSize(newInputSize);
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
setSelected(newSelected);
|
|
53
|
+
if (!value) return updateState({
|
|
54
|
+
filtered: []
|
|
55
|
+
});
|
|
56
|
+
if (actions.search) return void actions.search(value);
|
|
57
|
+
updateState({
|
|
58
|
+
filtered: filterOptions(computeUnselected(options, selected), value)
|
|
59
|
+
});
|
|
127
60
|
};
|
|
128
61
|
const handleKeyDown = (event)=>{
|
|
129
62
|
if ("Backspace" === event.key) removeLast();
|
|
130
63
|
if ("Enter" === event.key) {
|
|
131
|
-
|
|
132
|
-
if (
|
|
64
|
+
const available = filtered.length ? filtered : computeUnselected(options, selected);
|
|
65
|
+
if (available[0]) handleAddOption(available[0]);
|
|
133
66
|
}
|
|
134
67
|
};
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
68
|
+
const currentDataOptions = useMemo(()=>{
|
|
69
|
+
const feedbackOptions = feedbackText(translation, options, filtered, selected, query, max);
|
|
70
|
+
if (feedbackOptions.length) return feedbackOptions;
|
|
71
|
+
if (filtered.length) return filtered;
|
|
72
|
+
return computeUnselected(options, selected);
|
|
73
|
+
}, [
|
|
74
|
+
query,
|
|
75
|
+
filtered,
|
|
76
|
+
selected,
|
|
77
|
+
options,
|
|
78
|
+
max
|
|
79
|
+
]);
|
|
80
|
+
const handleClickOutside = (event)=>{
|
|
81
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) setShowList(false);
|
|
138
82
|
};
|
|
83
|
+
const clearSelected = ()=>updateState({
|
|
84
|
+
selected: []
|
|
85
|
+
});
|
|
139
86
|
const handleAddAll = (event)=>{
|
|
140
87
|
event.preventDefault();
|
|
141
|
-
if (
|
|
142
|
-
|
|
88
|
+
if (max) {
|
|
89
|
+
if (selected.length) {
|
|
90
|
+
const index = selected.length - max;
|
|
91
|
+
const toAdd = unselected.slice(0, index);
|
|
92
|
+
updateState({
|
|
93
|
+
selected: [
|
|
94
|
+
...selected,
|
|
95
|
+
...toAdd
|
|
96
|
+
],
|
|
97
|
+
unselected: []
|
|
98
|
+
});
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
updateState({
|
|
102
|
+
selected: options.slice(0, max),
|
|
103
|
+
unselected: []
|
|
104
|
+
});
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
updateState({
|
|
108
|
+
selected: options,
|
|
109
|
+
unselected: []
|
|
110
|
+
});
|
|
143
111
|
};
|
|
144
|
-
const canShowSelectAll = ()=>{
|
|
112
|
+
const canShowSelectAll = useMemo(()=>{
|
|
145
113
|
if (!selectAll) return;
|
|
146
|
-
if (selected.length === options.length) return;
|
|
147
|
-
if (
|
|
148
|
-
if (
|
|
114
|
+
if (selected.length === total || selected.length === options.length) return;
|
|
115
|
+
if (query) return;
|
|
116
|
+
if (max && max === selected.length) return;
|
|
149
117
|
return handleAddAll;
|
|
150
|
-
};
|
|
151
|
-
useEffect(()=>{
|
|
152
|
-
if (showList) document.addEventListener("click", handleClickOutside, true);
|
|
153
|
-
return ()=>{
|
|
154
|
-
document.removeEventListener("click", handleClickOutside, true);
|
|
155
|
-
};
|
|
156
|
-
}, [
|
|
157
|
-
showList
|
|
158
|
-
]);
|
|
159
|
-
useEffect(()=>{
|
|
160
|
-
if (0 === selected.length) return void setUnselected(options);
|
|
161
|
-
const newUnselected = options.filter((option)=>!selected.some((opt)=>opt.value === option.value));
|
|
162
|
-
setUnselected(newUnselected);
|
|
163
118
|
}, [
|
|
164
|
-
|
|
119
|
+
query,
|
|
120
|
+
filtered,
|
|
121
|
+
selected,
|
|
122
|
+
options,
|
|
123
|
+
max
|
|
165
124
|
]);
|
|
166
125
|
useEffect(()=>{
|
|
167
|
-
if (
|
|
126
|
+
if (showList) document.addEventListener("mousedown", handleClickOutside);
|
|
127
|
+
return ()=>document.removeEventListener("mousedown", handleClickOutside);
|
|
168
128
|
}, [
|
|
169
|
-
|
|
170
|
-
]);
|
|
171
|
-
useEffect(()=>{
|
|
172
|
-
if (value.length) return;
|
|
173
|
-
if (JSON.stringify(prevOptionsRef.current) !== JSON.stringify(options)) {
|
|
174
|
-
setUnselected(options);
|
|
175
|
-
prevOptionsRef.current = options;
|
|
176
|
-
}
|
|
177
|
-
}, [
|
|
178
|
-
options
|
|
179
|
-
]);
|
|
180
|
-
useEffect(()=>{
|
|
181
|
-
if (JSON.stringify(valueRef.current) !== JSON.stringify(value)) {
|
|
182
|
-
valueRef.current = value;
|
|
183
|
-
if (value.length > 0) {
|
|
184
|
-
const newUnselected = [
|
|
185
|
-
...options.filter((opt)=>!value.includes(opt)),
|
|
186
|
-
...value.filter((opt)=>!options.includes(opt))
|
|
187
|
-
];
|
|
188
|
-
setSelected(value);
|
|
189
|
-
setUnselected(newUnselected);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}, [
|
|
193
|
-
value
|
|
129
|
+
showList
|
|
194
130
|
]);
|
|
131
|
+
const feedBackHelpText = getHelpTextFeedbackType(feedback, disabled);
|
|
132
|
+
const toggleList = (event)=>{
|
|
133
|
+
event.stopPropagation();
|
|
134
|
+
setShowList((prev)=>!prev);
|
|
135
|
+
};
|
|
136
|
+
const handleClickContainer = (event)=>{
|
|
137
|
+
event.stopPropagation();
|
|
138
|
+
if (!showList) setShowList(true);
|
|
139
|
+
inputRef.current?.focus();
|
|
140
|
+
};
|
|
195
141
|
return /*#__PURE__*/ jsxs(MultiSelectWrapper, {
|
|
196
|
-
ref: containerRef,
|
|
197
142
|
children: [
|
|
198
143
|
/*#__PURE__*/ jsxs(LabelContainer, {
|
|
199
|
-
required: required,
|
|
200
144
|
children: [
|
|
201
|
-
/*#__PURE__*/
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}),
|
|
207
|
-
optional && /*#__PURE__*/ jsx("span", {
|
|
208
|
-
children: optional
|
|
209
|
-
}),
|
|
210
|
-
required && /*#__PURE__*/ jsx("span", {
|
|
211
|
-
children: "*"
|
|
212
|
-
})
|
|
213
|
-
]
|
|
145
|
+
label && /*#__PURE__*/ jsx(Label, {
|
|
146
|
+
text: label,
|
|
147
|
+
subtext: sublabel,
|
|
148
|
+
required: required,
|
|
149
|
+
htmlFor: name
|
|
214
150
|
}),
|
|
215
|
-
selected.length >
|
|
216
|
-
onClick:
|
|
151
|
+
selected.length > 0 && /*#__PURE__*/ jsx("button", {
|
|
152
|
+
onClick: clearSelected,
|
|
217
153
|
children: translation("remove_all")
|
|
218
154
|
})
|
|
219
155
|
]
|
|
220
156
|
}),
|
|
221
157
|
/*#__PURE__*/ jsxs(MultiSelectContainer, {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
158
|
+
ref: containerRef,
|
|
159
|
+
onClick: handleClickContainer,
|
|
160
|
+
feedback: feedback,
|
|
161
|
+
disabled: disabled,
|
|
162
|
+
$active: showList,
|
|
226
163
|
children: [
|
|
164
|
+
"string" == typeof icon ? /*#__PURE__*/ jsx(Icon, {
|
|
165
|
+
name: icon,
|
|
166
|
+
color: COLOR_NEUTRAL_DARK
|
|
167
|
+
}) : icon,
|
|
227
168
|
/*#__PURE__*/ jsxs(BadgesContainer, {
|
|
228
169
|
children: [
|
|
229
|
-
selected
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}, option.value))
|
|
234
|
-
}),
|
|
170
|
+
selected.map((option)=>/*#__PURE__*/ jsx(Badge, {
|
|
171
|
+
text: option.label,
|
|
172
|
+
remove: ()=>handleRemoveOption(option)
|
|
173
|
+
}, option.value)),
|
|
235
174
|
/*#__PURE__*/ jsx(ResizableInput, {
|
|
236
175
|
type: "text",
|
|
237
176
|
name: name,
|
|
238
177
|
placeholder: selected.length ? "" : placeholder,
|
|
239
178
|
ref: inputRef,
|
|
240
|
-
value:
|
|
179
|
+
value: query,
|
|
241
180
|
onKeyDown: handleKeyDown,
|
|
242
181
|
onChange: handleChange,
|
|
243
182
|
size: inputSize,
|
|
244
|
-
wide: 0 === selected.length
|
|
245
|
-
...rest
|
|
183
|
+
wide: 0 === selected.length
|
|
246
184
|
})
|
|
247
185
|
]
|
|
248
186
|
}),
|
|
249
|
-
|
|
187
|
+
/*#__PURE__*/ jsx(RotateButton, {
|
|
188
|
+
rotate: showList,
|
|
189
|
+
onClick: toggleList
|
|
190
|
+
}),
|
|
191
|
+
!!max && /*#__PURE__*/ jsx(MaxItemsIndicator, {
|
|
250
192
|
children: /*#__PURE__*/ jsxs("span", {
|
|
251
193
|
children: [
|
|
252
194
|
selected.length,
|
|
253
195
|
"/",
|
|
254
|
-
|
|
196
|
+
max
|
|
255
197
|
]
|
|
256
198
|
})
|
|
257
|
-
})
|
|
199
|
+
}),
|
|
258
200
|
showList && /*#__PURE__*/ jsx(MultiSelectList, {
|
|
259
|
-
options:
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
201
|
+
options: currentDataOptions,
|
|
202
|
+
translation: translation,
|
|
203
|
+
onClickOption: (e, option)=>handleAddOption(option),
|
|
204
|
+
loading: loading,
|
|
205
|
+
addAll: canShowSelectAll,
|
|
206
|
+
onLoadMore: onLoadMore
|
|
264
207
|
})
|
|
265
208
|
]
|
|
266
209
|
}),
|
|
267
|
-
/*#__PURE__*/
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
isError && /*#__PURE__*/ jsx(Icon, {
|
|
272
|
-
name: "ui warning-circle",
|
|
273
|
-
size: "1rem",
|
|
274
|
-
color: "currentColor"
|
|
275
|
-
}),
|
|
276
|
-
/*#__PURE__*/ jsx("span", {
|
|
277
|
-
children: helpText
|
|
278
|
-
})
|
|
279
|
-
]
|
|
210
|
+
helpText && /*#__PURE__*/ jsx(HelpText, {
|
|
211
|
+
text: helpText,
|
|
212
|
+
feedback: feedBackHelpText,
|
|
213
|
+
icon: helpIcon
|
|
280
214
|
})
|
|
281
215
|
]
|
|
282
216
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FieldFeedbackType } from '../../types/feedback';
|
|
1
2
|
export declare const MultiSelectWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
2
3
|
interface labelProps {
|
|
3
4
|
required?: boolean;
|
|
@@ -8,6 +9,11 @@ interface MultiSelectContainerProps {
|
|
|
8
9
|
isError?: boolean;
|
|
9
10
|
isSuccess?: boolean;
|
|
10
11
|
}
|
|
12
|
+
interface MultiSelectContainerProps {
|
|
13
|
+
feedback?: FieldFeedbackType;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
$active?: boolean;
|
|
16
|
+
}
|
|
11
17
|
export declare const MultiSelectContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, MultiSelectContainerProps>> & string;
|
|
12
18
|
export declare const BadgesContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
13
19
|
interface ResizableInputProps {
|
|
@@ -16,9 +22,4 @@ interface ResizableInputProps {
|
|
|
16
22
|
}
|
|
17
23
|
export declare const ResizableInput: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, ResizableInputProps>> & string;
|
|
18
24
|
export declare const MaxItemsIndicator: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
19
|
-
interface HelpTextProps {
|
|
20
|
-
isError?: boolean;
|
|
21
|
-
isSuccess?: boolean;
|
|
22
|
-
}
|
|
23
|
-
export declare const HelpText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, HelpTextProps>> & string;
|
|
24
25
|
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import styled_components, { keyframes } from "styled-components";
|
|
2
|
-
import { COLOR_ACCENT_DARK, COLOR_ACCENT_MEDIUM,
|
|
2
|
+
import { COLOR_ACCENT_DARK, COLOR_ACCENT_MEDIUM, COLOR_NEUTRAL_DARK, COLOR_NEUTRAL_DAY, COLOR_NEUTRAL_DUSK, COLOR_NEUTRAL_LIGHTER, COLOR_NEUTRAL_MEDIUM, FONT_WEIGHT_BOLD, FONT_WEIGHT_MEDIUM } from "@ftdata/f-tokens";
|
|
3
|
+
import { selectColorModifier } from "../fields/modifiers/selectColorModifier.js";
|
|
3
4
|
const MultiSelectWrapper = styled_components.div`
|
|
4
5
|
display: flex;
|
|
5
6
|
flex-direction: column;
|
|
@@ -18,34 +19,13 @@ const showButton = keyframes`
|
|
|
18
19
|
`;
|
|
19
20
|
const LabelContainer = styled_components.div`
|
|
20
21
|
display: flex;
|
|
21
|
-
gap: ${({ required })=>required ?
|
|
22
|
+
gap: ${({ required })=>required ? '0' : '0.5rem'};
|
|
22
23
|
position: relative;
|
|
23
24
|
justify-content: space-between;
|
|
24
25
|
align-items: flex-end;
|
|
25
26
|
|
|
26
|
-
div {
|
|
27
|
-
max-width: 70%;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
label {
|
|
31
|
-
color: ${COLOR_NEUTRAL_DUSK};
|
|
32
|
-
font-size: 0.875rem;
|
|
33
|
-
font-weight: ${FONT_WEIGHT_BOLD};
|
|
34
|
-
line-height: 1rem;
|
|
35
|
-
white-space: normal;
|
|
36
|
-
word-wrap: break-word;
|
|
37
|
-
overflow-wrap: break-word;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
span {
|
|
41
|
-
margin-left: ${({ required })=>required ? "0" : "0.5rem"};
|
|
42
|
-
color: ${({ required })=>required ? COLOR_DANGER_MEDIUM : COLOR_NEUTRAL_DARK};
|
|
43
|
-
font-size: 0.875rem;
|
|
44
|
-
font-weight: ${FONT_WEIGHT_BOLD};
|
|
45
|
-
line-height: 1rem;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
27
|
button {
|
|
28
|
+
white-space: nowrap;
|
|
49
29
|
color: ${COLOR_ACCENT_MEDIUM};
|
|
50
30
|
font-size: 0.875rem;
|
|
51
31
|
font-weight: ${FONT_WEIGHT_BOLD};
|
|
@@ -58,48 +38,34 @@ const LabelContainer = styled_components.div`
|
|
|
58
38
|
}
|
|
59
39
|
}
|
|
60
40
|
`;
|
|
61
|
-
const boxShadows = {
|
|
62
|
-
focused: {
|
|
63
|
-
default: `inset 0 0 0 2px ${COLOR_NEUTRAL_MEDIUM}`,
|
|
64
|
-
error: `inset 0 0 0 2px ${COLOR_DANGER_MEDIUM}`,
|
|
65
|
-
success: `inset 0 0 0 2px ${COLOR_SUCCESS_MEDIUM}`
|
|
66
|
-
},
|
|
67
|
-
blurred: {
|
|
68
|
-
default: `inset 0 0 0 1px ${COLOR_NEUTRAL_MEDIUM}`,
|
|
69
|
-
error: `inset 0 0 0 1px ${COLOR_DANGER_MEDIUM}`,
|
|
70
|
-
success: `inset 0 0 0 1px ${COLOR_SUCCESS_MEDIUM}`
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
const verifyBoxShadow = (isFocused, isError, isSuccess)=>{
|
|
74
|
-
if (isFocused) {
|
|
75
|
-
if (isError) return boxShadows.focused.error;
|
|
76
|
-
if (isSuccess) return boxShadows.focused.success;
|
|
77
|
-
return boxShadows.focused.default;
|
|
78
|
-
}
|
|
79
|
-
if (!isFocused) {
|
|
80
|
-
if (isError) return boxShadows.blurred.error;
|
|
81
|
-
if (isSuccess) return boxShadows.blurred.success;
|
|
82
|
-
return boxShadows.blurred.default;
|
|
83
|
-
}
|
|
84
|
-
return `inset 0 0 0 1px ${COLOR_NEUTRAL_MEDIUM}`;
|
|
85
|
-
};
|
|
86
41
|
const MultiSelectContainer = styled_components.div`
|
|
87
42
|
background-color: ${COLOR_NEUTRAL_DAY};
|
|
88
|
-
box-shadow: ${({ isFocused, isError, isSuccess })=>verifyBoxShadow(isFocused, isError, isSuccess)};
|
|
89
43
|
border-radius: 0.25rem;
|
|
90
44
|
display: flex;
|
|
91
45
|
flex-wrap: wrap;
|
|
92
46
|
gap: 0.5rem;
|
|
93
|
-
padding: 0.5rem;
|
|
47
|
+
padding: 0.5rem 0.5rem 0.5rem 1rem;
|
|
94
48
|
width: 100%;
|
|
49
|
+
box-shadow: 0 0 0
|
|
50
|
+
${({ $active })=>$active ? '2px' : '1px'}${COLOR_NEUTRAL_MEDIUM};
|
|
95
51
|
position: relative;
|
|
52
|
+
|
|
53
|
+
&:focus-within {
|
|
54
|
+
box-shadow: 0px 0px 0px 2px ${COLOR_NEUTRAL_MEDIUM};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
${({ disabled, feedback, $active })=>disabled ? `
|
|
58
|
+
background-color: ${COLOR_NEUTRAL_LIGHTER};
|
|
59
|
+
box-shadow: 0 0 0 1px ${COLOR_NEUTRAL_MEDIUM};
|
|
60
|
+
cursor: not-allowed;
|
|
61
|
+
` : selectColorModifier(feedback, $active)}
|
|
96
62
|
`;
|
|
97
63
|
const BadgesContainer = styled_components.div`
|
|
98
64
|
background-color: ${COLOR_NEUTRAL_DAY};
|
|
99
65
|
display: flex;
|
|
100
66
|
flex-wrap: wrap;
|
|
101
67
|
gap: 0.5rem;
|
|
102
|
-
|
|
68
|
+
flex: 1;
|
|
103
69
|
max-height: 160px;
|
|
104
70
|
overflow-y: auto;
|
|
105
71
|
|
|
@@ -127,7 +93,7 @@ const ResizableInput = styled_components.input`
|
|
|
127
93
|
line-height: 1rem;
|
|
128
94
|
font-weight: ${FONT_WEIGHT_MEDIUM};
|
|
129
95
|
padding: 0.25rem 0;
|
|
130
|
-
width: ${({ size, wide })=>wide ?
|
|
96
|
+
width: ${({ size, wide })=>wide ? '100%' : size ? `${size}rem` : '1rem'};
|
|
131
97
|
|
|
132
98
|
&::placeholder {
|
|
133
99
|
color: ${COLOR_NEUTRAL_DARK};
|
|
@@ -150,16 +116,4 @@ const MaxItemsIndicator = styled_components.div`
|
|
|
150
116
|
font-weight: ${FONT_WEIGHT_BOLD};
|
|
151
117
|
}
|
|
152
118
|
`;
|
|
153
|
-
|
|
154
|
-
color: ${({ isError, isSuccess })=>isError ? COLOR_DANGER_MEDIUM : isSuccess ? COLOR_SUCCESS_MEDIUM : COLOR_NEUTRAL_DARK};
|
|
155
|
-
display: flex;
|
|
156
|
-
gap: 0.25rem;
|
|
157
|
-
align-items: center;
|
|
158
|
-
|
|
159
|
-
span {
|
|
160
|
-
font-size: 0.875rem;
|
|
161
|
-
line-height: 1rem;
|
|
162
|
-
font-weight: ${FONT_WEIGHT_MEDIUM};
|
|
163
|
-
}
|
|
164
|
-
`;
|
|
165
|
-
export { BadgesContainer, HelpText, LabelContainer, MaxItemsIndicator, MultiSelectContainer, MultiSelectWrapper, ResizableInput };
|
|
119
|
+
export { BadgesContainer, LabelContainer, MaxItemsIndicator, MultiSelectContainer, MultiSelectWrapper, ResizableInput };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type RowComponentProps } from "react-window";
|
|
2
|
+
import { ISelectOption } from "../..";
|
|
3
|
+
export interface RowProps {
|
|
4
|
+
data: ISelectOption[];
|
|
5
|
+
onClickOption?: (event: React.MouseEvent<HTMLDivElement>, option: ISelectOption) => void;
|
|
6
|
+
selectedOption?: ISelectOption | null;
|
|
7
|
+
showTooltip: (event: React.MouseEvent<HTMLDivElement>, text: string) => void;
|
|
8
|
+
hideTooltip: () => void;
|
|
9
|
+
handleCustomAction: (action: () => void) => void;
|
|
10
|
+
}
|
|
11
|
+
export default function Row({ index, style, data, onClickOption, selectedOption, showTooltip, hideTooltip, handleCustomAction, }: RowComponentProps<RowProps>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { OptionContainer } from "./style.js";
|
|
3
|
+
function Row({ index, style, data, onClickOption, selectedOption, showTooltip, hideTooltip, handleCustomAction }) {
|
|
4
|
+
const option = data[index];
|
|
5
|
+
const isSelected = selectedOption ? option.value === selectedOption.value : false;
|
|
6
|
+
const handleShowTooltip = (event)=>{
|
|
7
|
+
const target = event.currentTarget.querySelector("span");
|
|
8
|
+
if (target && target.scrollWidth > target.clientWidth) return void showTooltip(event, option.label);
|
|
9
|
+
};
|
|
10
|
+
const handleClick = (event)=>{
|
|
11
|
+
if (option.action) return void handleCustomAction(option.action);
|
|
12
|
+
if (onClickOption) onClickOption(event, option);
|
|
13
|
+
};
|
|
14
|
+
return /*#__PURE__*/ jsxs(OptionContainer, {
|
|
15
|
+
style: style,
|
|
16
|
+
isSelected: isSelected,
|
|
17
|
+
onMouseEnter: handleShowTooltip,
|
|
18
|
+
onMouseLeave: hideTooltip,
|
|
19
|
+
onClick: handleClick,
|
|
20
|
+
className: option.action ? "action" : "",
|
|
21
|
+
children: [
|
|
22
|
+
/*#__PURE__*/ jsx("span", {
|
|
23
|
+
children: option.label
|
|
24
|
+
}),
|
|
25
|
+
option.chip || null
|
|
26
|
+
]
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export { Row as default };
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
export declare const SelectDropdown: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
2
1
|
interface OptionContainerProps {
|
|
3
2
|
isSelected?: boolean;
|
|
4
3
|
}
|
|
5
4
|
export declare const OptionContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, OptionContainerProps>> & string;
|
|
6
|
-
export declare const LoadingContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
7
5
|
export declare const CustomAction: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "isSelected"> & OptionContainerProps, never>> & string;
|
|
8
6
|
export {};
|