@ftdata/ui 0.0.9 → 0.0.11

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.
Files changed (84) hide show
  1. package/dist/components/DoubleList/DoubleList.stories.d.ts +2 -2
  2. package/dist/components/DoubleList/DoubleList.stories.js +43 -43
  3. package/dist/components/DoubleList/Row/index.d.ts +4 -0
  4. package/dist/components/DoubleList/Row/index.js +12 -0
  5. package/dist/components/DoubleList/Row/style.d.ts +1 -0
  6. package/dist/components/DoubleList/Row/style.js +31 -0
  7. package/dist/components/DoubleList/index.js +27 -35
  8. package/dist/components/DoubleList/style.d.ts +0 -1
  9. package/dist/components/DoubleList/style.js +2 -31
  10. package/dist/components/Menu/Menu.stories.d.ts +6 -0
  11. package/dist/components/Menu/Menu.stories.js +116 -0
  12. package/dist/components/Menu/index.js +29 -14
  13. package/dist/components/Menu/styles.d.ts +1 -0
  14. package/dist/components/Menu/styles.js +44 -28
  15. package/dist/components/MultiSelect/MultiSelectList/Row/index.d.ts +7 -0
  16. package/dist/components/MultiSelect/MultiSelectList/Row/index.js +26 -0
  17. package/dist/components/MultiSelect/MultiSelectList/Row/style.d.ts +6 -0
  18. package/dist/components/MultiSelect/MultiSelectList/Row/style.js +48 -0
  19. package/dist/components/MultiSelect/MultiSelectList/index.d.ts +4 -3
  20. package/dist/components/MultiSelect/MultiSelectList/index.js +51 -41
  21. package/dist/components/MultiSelect/MultiSelectList/style.d.ts +0 -1
  22. package/dist/components/MultiSelect/MultiSelectList/style.js +2 -31
  23. package/dist/components/MultiSelect/helpers/addOption.d.ts +5 -0
  24. package/dist/components/MultiSelect/helpers/addOption.js +14 -0
  25. package/dist/components/MultiSelect/helpers/computeUnselected.d.ts +2 -0
  26. package/dist/components/MultiSelect/helpers/computeUnselected.js +2 -0
  27. package/dist/components/MultiSelect/helpers/feedbackText.d.ts +5 -0
  28. package/dist/components/MultiSelect/helpers/feedbackText.js +30 -0
  29. package/dist/components/MultiSelect/helpers/filterOptions.d.ts +2 -0
  30. package/dist/components/MultiSelect/helpers/filterOptions.js +5 -0
  31. package/dist/components/MultiSelect/helpers/removeOptions.d.ts +5 -0
  32. package/dist/components/MultiSelect/helpers/removeOptions.js +9 -0
  33. package/dist/components/MultiSelect/index.d.ts +29 -14
  34. package/dist/components/MultiSelect/index.js +149 -215
  35. package/dist/components/MultiSelect/styles.d.ts +6 -5
  36. package/dist/components/MultiSelect/styles.js +20 -66
  37. package/dist/components/Select/List/Row/index.d.ts +11 -0
  38. package/dist/components/Select/List/Row/index.js +29 -0
  39. package/dist/components/{CustomSelect/CustomSelectList → Select/List/Row}/style.d.ts +0 -2
  40. package/dist/components/{CustomSelect/CustomSelectList → Select/List/Row}/style.js +1 -54
  41. package/dist/components/Select/List/index.d.ts +12 -0
  42. package/dist/components/Select/List/index.js +63 -0
  43. package/dist/components/Select/List/style.d.ts +2 -0
  44. package/dist/components/Select/List/style.js +56 -0
  45. package/dist/components/Select/index.d.ts +34 -0
  46. package/dist/components/{CustomSelect → Select}/index.js +11 -9
  47. package/dist/components/{CustomSelect → Select}/styles.d.ts +2 -2
  48. package/dist/components/{CustomSelect → Select}/styles.js +6 -8
  49. package/dist/components/fields/components/HelpText/index.d.ts +8 -0
  50. package/dist/components/fields/components/HelpText/index.js +35 -0
  51. package/dist/components/fields/components/HelpText/modifiers/colors.d.ts +4 -0
  52. package/dist/components/fields/components/HelpText/modifiers/colors.js +9 -0
  53. package/dist/components/fields/components/HelpText/styles.d.ts +2 -0
  54. package/dist/components/fields/components/HelpText/styles.js +19 -0
  55. package/dist/components/fields/components/Label/index.d.ts +8 -0
  56. package/dist/components/fields/components/Label/index.js +22 -0
  57. package/dist/components/fields/components/Label/styles.d.ts +5 -0
  58. package/dist/components/fields/components/Label/styles.js +28 -0
  59. package/dist/components/fields/components/RotateButton/index.d.ts +6 -0
  60. package/dist/components/fields/components/RotateButton/index.js +13 -0
  61. package/dist/components/fields/components/RotateButton/styles.d.ts +5 -0
  62. package/dist/components/fields/components/RotateButton/styles.js +10 -0
  63. package/dist/components/fields/helpers/getFeedbackType.d.ts +2 -0
  64. package/dist/components/fields/helpers/getFeedbackType.js +11 -0
  65. package/dist/components/fields/modifiers/color_modifiers.d.ts +2 -0
  66. package/dist/components/fields/modifiers/color_modifiers.js +7 -0
  67. package/dist/components/fields/modifiers/inputColorModifier.d.ts +2 -0
  68. package/dist/components/fields/modifiers/inputColorModifier.js +14 -0
  69. package/dist/components/fields/modifiers/selectColorModifier.d.ts +2 -0
  70. package/dist/components/fields/modifiers/selectColorModifier.js +10 -0
  71. package/dist/index.d.ts +3 -2
  72. package/dist/index.js +2 -2
  73. package/dist/style/base.css +2 -3
  74. package/dist/types/feedback.d.ts +1 -0
  75. package/package.json +2 -2
  76. package/dist/components/CustomSelect/CustomSelect.stories.d.ts +0 -73
  77. package/dist/components/CustomSelect/CustomSelect.stories.js +0 -477
  78. package/dist/components/CustomSelect/CustomSelectList/index.d.ts +0 -10
  79. package/dist/components/CustomSelect/CustomSelectList/index.js +0 -66
  80. package/dist/components/CustomSelect/index.d.ts +0 -30
  81. package/dist/components/MultiSelect/MultiSelect.stories.d.ts +0 -61
  82. package/dist/components/MultiSelect/MultiSelect.stories.js +0 -336
  83. /package/dist/components/MultiSelect/{calcTextSize.d.ts → helpers/calcTextSize.d.ts} +0 -0
  84. /package/dist/components/MultiSelect/{calcTextSize.js → helpers/calcTextSize.js} +0 -0
@@ -1,282 +1,216 @@
1
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
- import { useEffect, useRef, useState } from "react";
3
- import { BadgesContainer, HelpText, LabelContainer, MaxItemsIndicator, MultiSelectContainer, MultiSelectWrapper, ResizableInput } from "./styles.js";
4
- import Badge from "./Badge/index.js";
5
- import MultiSelectList from "./MultiSelectList/index.js";
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
- function MultiSelect({ helpText, label, isLoading, name, onChangeItems, optional, options, required, maxItems, placeholder, selectAll, isError, value = [], isSuccess, translation, ...rest }) {
9
- const [unselected, setUnselected] = useState([]);
10
- const [selected, setSelected] = useState([]);
11
- const [filtered, setFiltered] = useState([]);
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 [inputValue, setInputValue] = useState("");
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 notFound = {
21
- value: "",
22
- label: translation("no_data_was_found")
23
- };
24
- const allSelected = {
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
- setSelected((prev)=>[
75
- ...prev,
76
- option
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 filter = (event)=>{
103
- if (!event.target.value) return void setFiltered([]);
104
- const valueNormalized = event.target.value.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
105
- const newFiltered = unselected.filter((option)=>{
106
- const labelNormalized = option.label.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
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
- if (newFiltered.length > 0) return void setFiltered(newFiltered);
110
- setFiltered([
111
- notFound
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
- filter(event);
48
+ const value = event.target.value;
49
+ setQuery(value);
116
50
  const textStyle = "500 14px Inter";
117
- const newInputSize = calcTextSize(event.target.value, textStyle, "rem");
51
+ const newInputSize = calcTextSize(value, textStyle, "rem");
118
52
  if (newInputSize) setInputSize(newInputSize);
119
- setInputValue(event.target.value);
120
- };
121
- const removeLast = ()=>{
122
- if (0 === selected.length) return;
123
- if ("" !== inputValue) return;
124
- const idx = selected.length - 1;
125
- const newSelected = selected.slice(0, idx);
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
- if (filtered.length > 0) return void addSelectedByEnter(filtered[0]);
132
- if (unselected.length > 0) return void addSelectedByEnter(unselected[0]);
64
+ const available = filtered.length ? filtered : computeUnselected(options, selected);
65
+ if (available[0]) handleAddOption(available[0]);
133
66
  }
134
67
  };
135
- const handleClearAll = (event)=>{
136
- event.preventDefault();
137
- setSelected([]);
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 (maxItems && maxItems > 0) return setSelected(options.slice(0, maxItems));
142
- setSelected(options);
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 (0 !== filtered.length) return;
148
- if (maxItems && 0 === maxItems || maxItems === selected.length) return;
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
- selected
119
+ query,
120
+ filtered,
121
+ selected,
122
+ options,
123
+ max
165
124
  ]);
166
125
  useEffect(()=>{
167
- if (onChangeItems) onChangeItems(selected);
126
+ if (showList) document.addEventListener("mousedown", handleClickOutside);
127
+ return ()=>document.removeEventListener("mousedown", handleClickOutside);
168
128
  }, [
169
- selected
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__*/ jsxs("div", {
202
- children: [
203
- /*#__PURE__*/ jsx("label", {
204
- htmlFor: name,
205
- children: label
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 > 3 && /*#__PURE__*/ jsx("button", {
216
- onClick: handleClearAll,
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
- onClick: toggleList,
223
- isFocused: isFocused,
224
- isSuccess: isSuccess,
225
- isError: isError,
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 && /*#__PURE__*/ jsx(Fragment, {
230
- children: selected.map((option)=>/*#__PURE__*/ jsx(Badge, {
231
- text: option.label,
232
- remove: ()=>removeSelected(option.value)
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: inputValue,
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
- maxItems && maxItems > 0 ? /*#__PURE__*/ jsx(MaxItemsIndicator, {
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
- maxItems
196
+ max
255
197
  ]
256
198
  })
257
- }) : "",
199
+ }),
258
200
  showList && /*#__PURE__*/ jsx(MultiSelectList, {
259
- options: computedOptions(),
260
- onClickOption: options.length ? addSelected : ()=>null,
261
- isLoading: isLoading,
262
- addAll: canShowSelectAll(),
263
- translation: translation
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__*/ jsxs(HelpText, {
268
- isError: isError,
269
- isSuccess: isSuccess,
270
- children: [
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, COLOR_DANGER_MEDIUM, COLOR_NEUTRAL_DARK, COLOR_NEUTRAL_DAY, COLOR_NEUTRAL_DUSK, COLOR_NEUTRAL_MEDIUM, COLOR_SUCCESS_MEDIUM, FONT_WEIGHT_BOLD, FONT_WEIGHT_MEDIUM } from "@ftdata/f-tokens";
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 ? "0" : "0.5rem"};
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
- width: 100%;
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 ? "100%" : size ? `${size}rem` : "1rem"};
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
- const HelpText = styled_components.div`
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 {};