@ftdata/ui 0.0.1

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 (265) hide show
  1. package/README.md +23 -0
  2. package/dist/assets/AddIcon.d.ts +3 -0
  3. package/dist/assets/AddIcon.js +35 -0
  4. package/dist/assets/ArrowLeftIcon.d.ts +2 -0
  5. package/dist/assets/ArrowLeftIcon.js +26 -0
  6. package/dist/assets/BackArrowIcon.d.ts +3 -0
  7. package/dist/assets/BackArrowIcon.js +35 -0
  8. package/dist/assets/BellIcon.d.ts +2 -0
  9. package/dist/assets/BellIcon.js +43 -0
  10. package/dist/assets/BuildingIcon.d.ts +2 -0
  11. package/dist/assets/BuildingIcon.js +15 -0
  12. package/dist/assets/BurgerMenu.d.ts +3 -0
  13. package/dist/assets/BurgerMenu.js +41 -0
  14. package/dist/assets/CancelSquareIcon.d.ts +3 -0
  15. package/dist/assets/CancelSquareIcon.js +36 -0
  16. package/dist/assets/CarretDownIcon.d.ts +3 -0
  17. package/dist/assets/CarretDownIcon.js +32 -0
  18. package/dist/assets/CavetDown.d.ts +2 -0
  19. package/dist/assets/CavetDown.js +18 -0
  20. package/dist/assets/CavetRight.d.ts +2 -0
  21. package/dist/assets/CavetRight.js +18 -0
  22. package/dist/assets/CavetUp.d.ts +2 -0
  23. package/dist/assets/CavetUp.js +18 -0
  24. package/dist/assets/CheckMarkIcon.d.ts +3 -0
  25. package/dist/assets/CheckMarkIcon.js +39 -0
  26. package/dist/assets/CheckmarkDone.d.ts +3 -0
  27. package/dist/assets/CheckmarkDone.js +27 -0
  28. package/dist/assets/CloseIcon.d.ts +2 -0
  29. package/dist/assets/CloseIcon.js +27 -0
  30. package/dist/assets/CommandIcon.d.ts +2 -0
  31. package/dist/assets/CommandIcon.js +77 -0
  32. package/dist/assets/DoneCircleIcon.d.ts +3 -0
  33. package/dist/assets/DoneCircleIcon.js +29 -0
  34. package/dist/assets/EmptyAlertDetail.d.ts +2 -0
  35. package/dist/assets/EmptyAlertDetail.js +451 -0
  36. package/dist/assets/EmptyPage.d.ts +3 -0
  37. package/dist/assets/EmptyPage.js +551 -0
  38. package/dist/assets/EyeIcon.d.ts +2 -0
  39. package/dist/assets/EyeIcon.js +35 -0
  40. package/dist/assets/FenceIcon.d.ts +2 -0
  41. package/dist/assets/FenceIcon.js +70 -0
  42. package/dist/assets/FolderCheckmark.d.ts +3 -0
  43. package/dist/assets/FolderCheckmark.js +44 -0
  44. package/dist/assets/FulltrackLogo.d.ts +3 -0
  45. package/dist/assets/FulltrackLogo.js +37 -0
  46. package/dist/assets/GlobeIcon.d.ts +2 -0
  47. package/dist/assets/GlobeIcon.js +61 -0
  48. package/dist/assets/GoogleIcon.d.ts +2 -0
  49. package/dist/assets/GoogleIcon.js +18 -0
  50. package/dist/assets/Group.js +2 -0
  51. package/dist/assets/MinusMarkIcon.d.ts +3 -0
  52. package/dist/assets/MinusMarkIcon.js +40 -0
  53. package/dist/assets/MosaicIcon.d.ts +3 -0
  54. package/dist/assets/MosaicIcon.js +41 -0
  55. package/dist/assets/NavLogo.d.ts +3 -0
  56. package/dist/assets/NavLogo.js +73 -0
  57. package/dist/assets/PinLocation.d.ts +2 -0
  58. package/dist/assets/PinLocation.js +31 -0
  59. package/dist/assets/PlusAddIcon.d.ts +2 -0
  60. package/dist/assets/PlusAddIcon.js +42 -0
  61. package/dist/assets/RefreshIcon.d.ts +2 -0
  62. package/dist/assets/RefreshIcon.js +16 -0
  63. package/dist/assets/SearchIcon.d.ts +3 -0
  64. package/dist/assets/SearchIcon.js +30 -0
  65. package/dist/assets/SendIcon.d.ts +3 -0
  66. package/dist/assets/SendIcon.js +20 -0
  67. package/dist/assets/StreetView.d.ts +2 -0
  68. package/dist/assets/StreetView.js +52 -0
  69. package/dist/assets/SwitchCheckMarkIcon.d.ts +3 -0
  70. package/dist/assets/SwitchCheckMarkIcon.js +40 -0
  71. package/dist/assets/WarningIcon.d.ts +2 -0
  72. package/dist/assets/WarningIcon.js +34 -0
  73. package/dist/assets/gif/how-to-use.js +2 -0
  74. package/dist/assets/iconMenu/SettingsIcon.d.ts +2 -0
  75. package/dist/assets/iconMenu/SettingsIcon.js +30 -0
  76. package/dist/assets/img/cover.js +2 -0
  77. package/dist/assets/img/map-sample.js +2 -0
  78. package/dist/assets/img/photo-goes-here.js +2 -0
  79. package/dist/assets/svg/chat.js +2 -0
  80. package/dist/assets/svg/colored-item.js +2 -0
  81. package/dist/assets/svg/mailbox-bro.js +2 -0
  82. package/dist/assets/svg/star-favorite.js +2 -0
  83. package/dist/assets/travolta.js +2 -0
  84. package/dist/components/Avatar/Avatar.stories.d.ts +33 -0
  85. package/dist/components/Avatar/Avatar.stories.js +177 -0
  86. package/dist/components/Avatar/index.d.ts +7 -0
  87. package/dist/components/Avatar/index.js +28 -0
  88. package/dist/components/Avatar/styles.d.ts +4 -0
  89. package/dist/components/Avatar/styles.js +37 -0
  90. package/dist/components/Avatar/utils/getAvatarColors.d.ts +6 -0
  91. package/dist/components/Avatar/utils/getAvatarColors.js +48 -0
  92. package/dist/components/Breadcrumb/Breadcrumb.stories.d.ts +17 -0
  93. package/dist/components/Breadcrumb/Breadcrumb.stories.js +51 -0
  94. package/dist/components/Breadcrumb/index.d.ts +10 -0
  95. package/dist/components/Breadcrumb/index.js +34 -0
  96. package/dist/components/Breadcrumb/styles.d.ts +9 -0
  97. package/dist/components/Breadcrumb/styles.js +43 -0
  98. package/dist/components/Button/Button.stories.d.ts +58 -0
  99. package/dist/components/Button/Button.stories.js +284 -0
  100. package/dist/components/Button/index.d.ts +26 -0
  101. package/dist/components/Button/index.js +69 -0
  102. package/dist/components/Button/modifiers.d.ts +8 -0
  103. package/dist/components/Button/modifiers.js +41 -0
  104. package/dist/components/Button/styles.d.ts +25 -0
  105. package/dist/components/Button/styles.js +111 -0
  106. package/dist/components/Checkbox/CheckMarkIcon.d.ts +3 -0
  107. package/dist/components/Checkbox/CheckMarkIcon.js +38 -0
  108. package/dist/components/Checkbox/Checkbox.stories.d.ts +35 -0
  109. package/dist/components/Checkbox/Checkbox.stories.js +101 -0
  110. package/dist/components/Checkbox/MinusMarkIcon.d.ts +3 -0
  111. package/dist/components/Checkbox/MinusMarkIcon.js +39 -0
  112. package/dist/components/Checkbox/index.d.ts +9 -0
  113. package/dist/components/Checkbox/index.js +40 -0
  114. package/dist/components/Checkbox/styles.d.ts +12 -0
  115. package/dist/components/Checkbox/styles.js +41 -0
  116. package/dist/components/Collapse/Colapse.stories.d.ts +10 -0
  117. package/dist/components/Collapse/Colapse.stories.js +108 -0
  118. package/dist/components/Collapse/index.d.ts +15 -0
  119. package/dist/components/Collapse/index.js +61 -0
  120. package/dist/components/Collapse/styles.d.ts +11 -0
  121. package/dist/components/Collapse/styles.js +23 -0
  122. package/dist/components/CustomSelect/CustomSelect.stories.d.ts +73 -0
  123. package/dist/components/CustomSelect/CustomSelect.stories.js +477 -0
  124. package/dist/components/CustomSelect/CustomSelectList/index.d.ts +10 -0
  125. package/dist/components/CustomSelect/CustomSelectList/index.js +66 -0
  126. package/dist/components/CustomSelect/CustomSelectList/style.d.ts +8 -0
  127. package/dist/components/CustomSelect/CustomSelectList/style.js +95 -0
  128. package/dist/components/CustomSelect/index.d.ts +30 -0
  129. package/dist/components/CustomSelect/index.js +193 -0
  130. package/dist/components/CustomSelect/styles.d.ts +22 -0
  131. package/dist/components/CustomSelect/styles.js +93 -0
  132. package/dist/components/DoubleList/DoubleList.stories.d.ts +13 -0
  133. package/dist/components/DoubleList/DoubleList.stories.js +82 -0
  134. package/dist/components/DoubleList/index.d.ts +9 -0
  135. package/dist/components/DoubleList/index.js +70 -0
  136. package/dist/components/DoubleList/style.d.ts +5 -0
  137. package/dist/components/DoubleList/style.js +92 -0
  138. package/dist/components/EmptyState/Empty.stories.d.ts +26 -0
  139. package/dist/components/EmptyState/Empty.stories.js +72 -0
  140. package/dist/components/EmptyState/index.d.ts +10 -0
  141. package/dist/components/EmptyState/index.js +48 -0
  142. package/dist/components/EmptyState/styles.d.ts +3 -0
  143. package/dist/components/EmptyState/styles.js +39 -0
  144. package/dist/components/Grid/Column/Column.stories.d.ts +26 -0
  145. package/dist/components/Grid/Column/Column.stories.js +335 -0
  146. package/dist/components/Grid/Column/index.d.ts +15 -0
  147. package/dist/components/Grid/Column/index.js +10 -0
  148. package/dist/components/Grid/Container/Container.stories.d.ts +11 -0
  149. package/dist/components/Grid/Container/Container.stories.js +114 -0
  150. package/dist/components/Grid/Container/index.d.ts +6 -0
  151. package/dist/components/Grid/Container/index.js +11 -0
  152. package/dist/components/Grid/Row/Row.stories.d.ts +22 -0
  153. package/dist/components/Grid/Row/Row.stories.js +248 -0
  154. package/dist/components/Grid/Row/index.d.ts +20 -0
  155. package/dist/components/Grid/Row/index.js +10 -0
  156. package/dist/components/Grid/index.d.ts +38 -0
  157. package/dist/components/Grid/index.js +121 -0
  158. package/dist/components/Grid/utils.d.ts +1 -0
  159. package/dist/components/Grid/utils.js +18 -0
  160. package/dist/components/Loading/Loading/index.d.ts +7 -0
  161. package/dist/components/Loading/Loading/index.js +9 -0
  162. package/dist/components/Loading/Loading.stories.d.ts +24 -0
  163. package/dist/components/Loading/Loading.stories.js +145 -0
  164. package/dist/components/Loading/index.d.ts +16 -0
  165. package/dist/components/Loading/index.js +98 -0
  166. package/dist/components/Menu/constants/icons.d.ts +17 -0
  167. package/dist/components/Menu/constants/icons.js +61 -0
  168. package/dist/components/Menu/helpers/createMenus.d.ts +2 -0
  169. package/dist/components/Menu/helpers/createMenus.js +20 -0
  170. package/dist/components/Menu/helpers/createSubMenus.d.ts +2 -0
  171. package/dist/components/Menu/helpers/createSubMenus.js +13 -0
  172. package/dist/components/Menu/helpers/generateColorScale.d.ts +1 -0
  173. package/dist/components/Menu/helpers/generateColorScale.js +62 -0
  174. package/dist/components/Menu/helpers/getLuminance.d.ts +1 -0
  175. package/dist/components/Menu/helpers/getLuminance.js +9 -0
  176. package/dist/components/Menu/index.d.ts +12 -0
  177. package/dist/components/Menu/index.js +108 -0
  178. package/dist/components/Menu/styles.d.ts +17 -0
  179. package/dist/components/Menu/styles.js +202 -0
  180. package/dist/components/Menu/types/IconKeysType.d.ts +2 -0
  181. package/dist/components/Menu/types/IconKeysType.js +0 -0
  182. package/dist/components/Menu/types/MenuItem.d.ts +26 -0
  183. package/dist/components/Menu/types/MenuItem.js +0 -0
  184. package/dist/components/MultiSelect/Badge/index.d.ts +6 -0
  185. package/dist/components/MultiSelect/Badge/index.js +31 -0
  186. package/dist/components/MultiSelect/Badge/styles.d.ts +1 -0
  187. package/dist/components/MultiSelect/Badge/styles.js +57 -0
  188. package/dist/components/MultiSelect/MultiSelect.stories.d.ts +61 -0
  189. package/dist/components/MultiSelect/MultiSelect.stories.js +336 -0
  190. package/dist/components/MultiSelect/MultiSelectList/index.d.ts +10 -0
  191. package/dist/components/MultiSelect/MultiSelectList/index.js +59 -0
  192. package/dist/components/MultiSelect/MultiSelectList/style.d.ts +3 -0
  193. package/dist/components/MultiSelect/MultiSelectList/style.js +82 -0
  194. package/dist/components/MultiSelect/calcTextSize.d.ts +1 -0
  195. package/dist/components/MultiSelect/calcTextSize.js +10 -0
  196. package/dist/components/MultiSelect/index.d.ts +24 -0
  197. package/dist/components/MultiSelect/index.js +284 -0
  198. package/dist/components/MultiSelect/styles.d.ts +24 -0
  199. package/dist/components/MultiSelect/styles.js +165 -0
  200. package/dist/components/Radio/Radio.stories.d.ts +18 -0
  201. package/dist/components/Radio/Radio.stories.js +30 -0
  202. package/dist/components/Radio/index.d.ts +7 -0
  203. package/dist/components/Radio/index.js +27 -0
  204. package/dist/components/Radio/story.d.ts +5 -0
  205. package/dist/components/Radio/story.js +47 -0
  206. package/dist/components/Radio/styles.d.ts +8 -0
  207. package/dist/components/Radio/styles.js +43 -0
  208. package/dist/components/StateAlert/StateAlert.stories.d.ts +46 -0
  209. package/dist/components/StateAlert/StateAlert.stories.js +189 -0
  210. package/dist/components/StateAlert/index.d.ts +22 -0
  211. package/dist/components/StateAlert/index.js +56 -0
  212. package/dist/components/StateAlert/styles.d.ts +7 -0
  213. package/dist/components/StateAlert/styles.js +124 -0
  214. package/dist/components/Switch/Switch.stories.d.ts +26 -0
  215. package/dist/components/Switch/Switch.stories.js +81 -0
  216. package/dist/components/Switch/index.d.ts +8 -0
  217. package/dist/components/Switch/index.js +26 -0
  218. package/dist/components/Switch/styles.d.ts +15 -0
  219. package/dist/components/Switch/styles.js +33 -0
  220. package/dist/components/Text/Paragraph/Paragraph.stories.d.ts +29 -0
  221. package/dist/components/Text/Paragraph/Paragraph.stories.js +124 -0
  222. package/dist/components/Text/Title/Title.stories.d.ts +41 -0
  223. package/dist/components/Text/Title/Title.stories.js +106 -0
  224. package/dist/components/Text/index.d.ts +3 -0
  225. package/dist/components/Text/index.js +17 -0
  226. package/dist/components/Text/styles.d.ts +23 -0
  227. package/dist/components/Text/styles.js +70 -0
  228. package/dist/components/TextArea/Textarea.stories.d.ts +33 -0
  229. package/dist/components/TextArea/Textarea.stories.js +65 -0
  230. package/dist/components/TextArea/index.d.ts +10 -0
  231. package/dist/components/TextArea/index.js +39 -0
  232. package/dist/components/TextArea/styles.d.ts +18 -0
  233. package/dist/components/TextArea/styles.js +88 -0
  234. package/dist/components/TooltipWrapper/Tooltip.stories.d.ts +21 -0
  235. package/dist/components/TooltipWrapper/Tooltip.stories.js +54 -0
  236. package/dist/components/TooltipWrapper/index.d.ts +20 -0
  237. package/dist/components/TooltipWrapper/index.js +56 -0
  238. package/dist/components/TooltipWrapper/styles.d.ts +6 -0
  239. package/dist/components/TooltipWrapper/styles.js +20 -0
  240. package/dist/components/Tooltips/Tooltips.stories.d.ts +25 -0
  241. package/dist/components/Tooltips/Tooltips.stories.js +139 -0
  242. package/dist/components/Tooltips/index.d.ts +8 -0
  243. package/dist/components/Tooltips/index.js +28 -0
  244. package/dist/components/Tooltips/styles.d.ts +5 -0
  245. package/dist/components/Tooltips/styles.js +37 -0
  246. package/dist/components/UserMenu/UserMenu.stories.d.ts +26 -0
  247. package/dist/components/UserMenu/UserMenu.stories.js +174 -0
  248. package/dist/components/UserMenu/index.d.ts +19 -0
  249. package/dist/components/UserMenu/index.js +64 -0
  250. package/dist/components/UserMenu/style.d.ts +2 -0
  251. package/dist/components/UserMenu/style.js +44 -0
  252. package/dist/index.d.ts +3 -0
  253. package/dist/index.js +3 -0
  254. package/dist/static/image/cover.png +0 -0
  255. package/dist/static/image/how-to-use.gif +0 -0
  256. package/dist/static/image/map-sample.png +0 -0
  257. package/dist/static/image/photo-goes-here.png +0 -0
  258. package/dist/static/image/travolta.jpg +0 -0
  259. package/dist/static/svg/Group.svg +5 -0
  260. package/dist/static/svg/chat.svg +10 -0
  261. package/dist/static/svg/colored-item.svg +9 -0
  262. package/dist/static/svg/mailbox-bro.svg +102 -0
  263. package/dist/static/svg/star-favorite.svg +3 -0
  264. package/dist/style/_reset.css +205 -0
  265. package/package.json +43 -0
@@ -0,0 +1,284 @@
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";
7
+ 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([]);
12
+ const [showList, setShowList] = useState(false);
13
+ const [inputValue, setInputValue] = useState("");
14
+ const [inputSize, setInputSize] = useState(0);
15
+ const [isFocused, setIsFocused] = useState(false);
16
+ const prevOptionsRef = useRef([]);
17
+ const valueRef = useRef([]);
18
+ const inputRef = useRef(null);
19
+ 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("");
73
+ setInputSize(1);
74
+ setSelected((prev)=>[
75
+ ...prev,
76
+ option
77
+ ]);
78
+ 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
+ };
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);
108
+ });
109
+ if (newFiltered.length > 0) return void setFiltered(newFiltered);
110
+ setFiltered([
111
+ notFound
112
+ ]);
113
+ };
114
+ const handleChange = (event)=>{
115
+ filter(event);
116
+ const textStyle = "500 14px Inter";
117
+ const newInputSize = calcTextSize(event.target.value, textStyle, "rem");
118
+ 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);
127
+ };
128
+ const handleKeyDown = (event)=>{
129
+ if ("Backspace" === event.key) removeLast();
130
+ if ("Enter" === event.key) {
131
+ if (filtered.length > 0) return void addSelectedByEnter(filtered[0]);
132
+ if (unselected.length > 0) return void addSelectedByEnter(unselected[0]);
133
+ }
134
+ };
135
+ const handleClearAll = (event)=>{
136
+ event.preventDefault();
137
+ setSelected([]);
138
+ };
139
+ const handleAddAll = (event)=>{
140
+ event.preventDefault();
141
+ if (maxItems && maxItems > 0) return setSelected(options.slice(0, maxItems));
142
+ setSelected(options);
143
+ };
144
+ const canShowSelectAll = ()=>{
145
+ 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;
149
+ 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
+ }, [
164
+ selected
165
+ ]);
166
+ useEffect(()=>{
167
+ if (onChangeItems) onChangeItems(selected);
168
+ }, [
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
194
+ ]);
195
+ return /*#__PURE__*/ jsxs(MultiSelectWrapper, {
196
+ ref: containerRef,
197
+ children: [
198
+ /*#__PURE__*/ jsxs(LabelContainer, {
199
+ required: required,
200
+ 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
+ ]
214
+ }),
215
+ selected.length > 3 && /*#__PURE__*/ jsx("button", {
216
+ onClick: handleClearAll,
217
+ children: translation("remove_all")
218
+ })
219
+ ]
220
+ }),
221
+ /*#__PURE__*/ jsxs(MultiSelectContainer, {
222
+ onClick: toggleList,
223
+ isFocused: isFocused,
224
+ isSuccess: isSuccess,
225
+ isError: isError,
226
+ children: [
227
+ /*#__PURE__*/ jsxs(BadgesContainer, {
228
+ 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
+ }),
235
+ /*#__PURE__*/ jsx(ResizableInput, {
236
+ type: "text",
237
+ name: name,
238
+ placeholder: selected.length ? "" : placeholder,
239
+ ref: inputRef,
240
+ value: inputValue,
241
+ onKeyDown: handleKeyDown,
242
+ onChange: handleChange,
243
+ size: inputSize,
244
+ wide: 0 === selected.length,
245
+ ...rest
246
+ })
247
+ ]
248
+ }),
249
+ maxItems && maxItems > 0 ? /*#__PURE__*/ jsx(MaxItemsIndicator, {
250
+ children: /*#__PURE__*/ jsxs("span", {
251
+ children: [
252
+ selected.length,
253
+ "/",
254
+ maxItems
255
+ ]
256
+ })
257
+ }) : "",
258
+ showList && /*#__PURE__*/ jsx(MultiSelectList, {
259
+ options: computedOptions(),
260
+ onClickOption: options.length ? addSelected : ()=>null,
261
+ isLoading: isLoading,
262
+ addAll: canShowSelectAll(),
263
+ translation: translation
264
+ })
265
+ ]
266
+ }),
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
+ ]
280
+ })
281
+ ]
282
+ });
283
+ }
284
+ export { MultiSelect as default };
@@ -0,0 +1,24 @@
1
+ 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
+ interface labelProps {
3
+ required?: boolean;
4
+ }
5
+ export declare const LabelContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, labelProps>> & string;
6
+ interface MultiSelectContainerProps {
7
+ isFocused?: boolean;
8
+ isError?: boolean;
9
+ isSuccess?: boolean;
10
+ }
11
+ 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
+ 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
+ interface ResizableInputProps {
14
+ size: number;
15
+ wide: boolean;
16
+ }
17
+ 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
+ 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
+ export {};
@@ -0,0 +1,165 @@
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";
3
+ const MultiSelectWrapper = styled_components.div`
4
+ display: flex;
5
+ flex-direction: column;
6
+ gap: 0.5rem;
7
+ width: 100%;
8
+ `;
9
+ const showButton = keyframes`
10
+ from {
11
+ opacity: 0.8;
12
+ transform: translateY(2px);
13
+ }
14
+ to {
15
+ opacity: 1;
16
+ transform: translateY(0);
17
+ }
18
+ `;
19
+ const LabelContainer = styled_components.div`
20
+ display: flex;
21
+ gap: ${({ required })=>required ? "0" : "0.5rem"};
22
+ position: relative;
23
+ justify-content: space-between;
24
+ align-items: flex-end;
25
+
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
+ button {
49
+ color: ${COLOR_ACCENT_MEDIUM};
50
+ font-size: 0.875rem;
51
+ font-weight: ${FONT_WEIGHT_BOLD};
52
+ line-height: 1rem;
53
+ animation: ${showButton} 0.15s ease-in forwards;
54
+ height: 1rem;
55
+
56
+ &:hover {
57
+ color: ${COLOR_ACCENT_DARK};
58
+ }
59
+ }
60
+ `;
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
+ const MultiSelectContainer = styled_components.div`
87
+ background-color: ${COLOR_NEUTRAL_DAY};
88
+ box-shadow: ${({ isFocused, isError, isSuccess })=>verifyBoxShadow(isFocused, isError, isSuccess)};
89
+ border-radius: 0.25rem;
90
+ display: flex;
91
+ flex-wrap: wrap;
92
+ gap: 0.5rem;
93
+ padding: 0.5rem;
94
+ width: 100%;
95
+ position: relative;
96
+ `;
97
+ const BadgesContainer = styled_components.div`
98
+ background-color: ${COLOR_NEUTRAL_DAY};
99
+ display: flex;
100
+ flex-wrap: wrap;
101
+ gap: 0.5rem;
102
+ width: 100%;
103
+ max-height: 160px;
104
+ overflow-y: auto;
105
+
106
+ &::-webkit-scrollbar-track {
107
+ background-color: #f4f4f4;
108
+ border-radius: 0 0.25rem 0.25rem 0;
109
+ }
110
+
111
+ &::-webkit-scrollbar {
112
+ width: 10px;
113
+ background: #f4f4f4;
114
+ border-radius: 0 0.25rem 0.25rem 0;
115
+ }
116
+
117
+ &::-webkit-scrollbar-thumb {
118
+ border-radius: 10px;
119
+ background: #d5d8da;
120
+ }
121
+ `;
122
+ const ResizableInput = styled_components.input`
123
+ outline: none;
124
+ border: none;
125
+ color: ${COLOR_NEUTRAL_DUSK};
126
+ font-size: 0.875rem;
127
+ line-height: 1rem;
128
+ font-weight: ${FONT_WEIGHT_MEDIUM};
129
+ padding: 0.25rem 0;
130
+ width: ${({ size, wide })=>wide ? "100%" : size ? `${size}rem` : "1rem"};
131
+
132
+ &::placeholder {
133
+ color: ${COLOR_NEUTRAL_DARK};
134
+ font-size: 0.875rem;
135
+ line-height: 1rem;
136
+ font-weight: ${FONT_WEIGHT_MEDIUM};
137
+ line-height: 1.5rem;
138
+ }
139
+ `;
140
+ const MaxItemsIndicator = styled_components.div`
141
+ display: flex;
142
+ align-items: center;
143
+ justify-content: flex-end;
144
+ width: 100%;
145
+
146
+ span {
147
+ color: ${COLOR_NEUTRAL_MEDIUM};
148
+ font-size: 0.75rem;
149
+ line-height: 0.75rem;
150
+ font-weight: ${FONT_WEIGHT_BOLD};
151
+ }
152
+ `;
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 };
@@ -0,0 +1,18 @@
1
+ import { Meta, StoryObj } from "@storybook/react";
2
+ import Radio from ".";
3
+ /**
4
+ * Radios são usados em formulários. Os usuários podem marcar apenas um dos botões de opção.
5
+ * Somente um botão de opção pode ser marcado por vez.
6
+ * Este componente também funciona com os atributos nativos de um HTML input element.
7
+ */
8
+ declare const meta: Meta<typeof Radio>;
9
+ export default meta;
10
+ type Story = StoryObj<typeof meta>;
11
+ /**
12
+ * Variação do Radio quando não está marcado.
13
+ */
14
+ export declare const Unchecked: Story;
15
+ /**
16
+ * Variação do Radio quando está marcado.
17
+ */
18
+ export declare const Checked: Story;
@@ -0,0 +1,30 @@
1
+ import index from "./index.js";
2
+ const meta = {
3
+ title: "DESIGN COMPONENTS/Radio",
4
+ component: index,
5
+ tags: [
6
+ "autodocs"
7
+ ],
8
+ parameters: {
9
+ layout: "centered"
10
+ },
11
+ argTypes: {
12
+ checked: {
13
+ description: "Define se o componente est\xe1 marcado."
14
+ }
15
+ }
16
+ };
17
+ const Radio_stories = meta;
18
+ const Unchecked = {
19
+ args: {
20
+ label: "Uncheked",
21
+ checked: false
22
+ }
23
+ };
24
+ const Checked = {
25
+ args: {
26
+ label: "Cheked",
27
+ checked: true
28
+ }
29
+ };
30
+ export { Checked, Unchecked, Radio_stories as default };
@@ -0,0 +1,7 @@
1
+ import React, { InputHTMLAttributes } from "react";
2
+ interface RadioProps extends InputHTMLAttributes<HTMLInputElement> {
3
+ checked: boolean;
4
+ label: string;
5
+ }
6
+ declare const Radio: React.FC<RadioProps>;
7
+ export default Radio;
@@ -0,0 +1,27 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import "react";
3
+ import { Input, Label } from "./styles.js";
4
+ import { Paragraph } from "../Text/index.js";
5
+ const Radio = ({ checked, disabled, label, name, ...rest })=>/*#__PURE__*/ jsxs(Fragment, {
6
+ children: [
7
+ /*#__PURE__*/ jsx(Input, {
8
+ checked: checked,
9
+ disabled: disabled,
10
+ id: name,
11
+ name: name,
12
+ type: "radio",
13
+ ...rest
14
+ }),
15
+ /*#__PURE__*/ jsx(Label, {
16
+ checked: checked,
17
+ disabled: disabled,
18
+ htmlFor: name,
19
+ children: /*#__PURE__*/ jsx(Paragraph, {
20
+ size: "md",
21
+ children: label
22
+ })
23
+ })
24
+ ]
25
+ });
26
+ const components_Radio = Radio;
27
+ export { components_Radio as default };
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ declare const RadioButton: React.FC<{
3
+ disabled: boolean;
4
+ }>;
5
+ export default RadioButton;
@@ -0,0 +1,47 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import index from "./index.js";
4
+ const RadioButton = ({ disabled })=>{
5
+ const [selectedValue, setSelectedValue] = useState("a");
6
+ const handleChange = (event)=>{
7
+ setSelectedValue(event.currentTarget.value);
8
+ };
9
+ return /*#__PURE__*/ jsxs(Fragment, {
10
+ children: [
11
+ /*#__PURE__*/ jsx(index, {
12
+ checked: "a" === selectedValue,
13
+ disabled: disabled,
14
+ onChange: handleChange,
15
+ value: "a",
16
+ name: "radio-button-demo1",
17
+ label: "Teste 1"
18
+ }),
19
+ /*#__PURE__*/ jsx(index, {
20
+ checked: "b" === selectedValue,
21
+ disabled: disabled,
22
+ onChange: handleChange,
23
+ value: "b",
24
+ name: "radio-button-demo2",
25
+ label: "Teste 2"
26
+ }),
27
+ /*#__PURE__*/ jsx(index, {
28
+ checked: "c" === selectedValue,
29
+ disabled: disabled,
30
+ onChange: handleChange,
31
+ value: "c",
32
+ name: "radio-button-demo3",
33
+ label: "Teste 3"
34
+ }),
35
+ /*#__PURE__*/ jsx(index, {
36
+ checked: "d" === selectedValue,
37
+ disabled: disabled,
38
+ onChange: handleChange,
39
+ value: "d",
40
+ name: "radio-button-demo4",
41
+ label: "Teste 4"
42
+ })
43
+ ]
44
+ });
45
+ };
46
+ const story = RadioButton;
47
+ export { story as default };
@@ -0,0 +1,8 @@
1
+ import { LabelHTMLAttributes } from "react";
2
+ interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {
3
+ checked: boolean;
4
+ disabled?: boolean;
5
+ }
6
+ export declare const Label: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").ClassAttributes<HTMLLabelElement> & LabelHTMLAttributes<HTMLLabelElement>, LabelProps>> & string;
7
+ export declare const Input: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").ClassAttributes<HTMLInputElement> & import("react").InputHTMLAttributes<HTMLInputElement>, never>> & string;
8
+ export {};
@@ -0,0 +1,43 @@
1
+ import styled_components from "styled-components";
2
+ import { BORDER_RADIUS_CIRCLE, BORDER_WIDTH_HAIRLINE, BORDER_WIDTH_THICK, COLOR_ACCENT_MEDIUM, COLOR_NEUTRAL_DARKER, COLOR_NEUTRAL_DAY, COLOR_NEUTRAL_DUSK, COLOR_NEUTRAL_LIGHT, COLOR_NEUTRAL_LIGHTER, COLOR_NEUTRAL_MEDIUM, SPACING_INLINE_03, SPACING_INLINE_04, SPACING_STACK_03 } from "@ftdata/f-tokens";
3
+ const Label = styled_components("label")`
4
+ box-sizing: border-box;
5
+ color: ${({ disabled })=>disabled ? COLOR_NEUTRAL_DARKER : COLOR_NEUTRAL_DUSK};
6
+ cursor: ${({ disabled })=>disabled ? "not-allowed" : "pointer"};
7
+ display: inline-block;
8
+ position: relative;
9
+ padding-left: ${SPACING_INLINE_04};
10
+
11
+ &:before,
12
+ &:after {
13
+ background: ${({ checked, disabled })=>disabled ? checked ? COLOR_NEUTRAL_DAY : COLOR_NEUTRAL_LIGHTER : COLOR_NEUTRAL_DAY};
14
+ border: ${({ disabled })=>disabled ? 0 : `${BORDER_WIDTH_HAIRLINE} solid
15
+ ${COLOR_NEUTRAL_LIGHT}`};
16
+ border-radius: ${BORDER_RADIUS_CIRCLE};
17
+ box-sizing: border-box;
18
+ content: "";
19
+ height: ${SPACING_STACK_03};
20
+ left: 0;
21
+ position: absolute;
22
+ top: 50%;
23
+ transform: translateY(-50%);
24
+ transition: 0.2s ease all;
25
+ width: ${SPACING_INLINE_03};
26
+ }
27
+
28
+ &:after {
29
+ border: ${BORDER_WIDTH_THICK} solid
30
+ ${({ disabled })=>disabled ? COLOR_NEUTRAL_MEDIUM : COLOR_ACCENT_MEDIUM};
31
+ height: ${SPACING_STACK_03};
32
+ opacity: ${({ checked })=>checked ? 1 : 0};
33
+ width: ${SPACING_INLINE_03};
34
+ }
35
+ `;
36
+ const Input = styled_components("input")`
37
+ box-sizing: border-box;
38
+ left: -9999px;
39
+ opacity: ${({ checked })=>checked ? 1 : 0};
40
+ position: absolute;
41
+ transform: scale(${({ checked })=>checked ? 1 : 0});
42
+ `;
43
+ export { Input, Label };