@cleen/ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (416) hide show
  1. package/package.json +54 -0
  2. package/src/charts/chart/Chart.tsx +82 -0
  3. package/src/charts/chart/constant.ts +50 -0
  4. package/src/charts/chart/index.ts +2 -0
  5. package/src/charts/chart/types/apexcharts.ts +9 -0
  6. package/src/charts/chart/variants/BellCurve/BellCurve.tsx +215 -0
  7. package/src/charts/chart/variants/BellCurve/constant.ts +112 -0
  8. package/src/charts/chart/variants/BellCurve/helper.ts +116 -0
  9. package/src/charts/chart/variants/BellCurve/index.ts +2 -0
  10. package/src/charts/chart/variants/BellCurve/types/bellCurve.ts +47 -0
  11. package/src/charts/chart/variants/BellCurve/types/props.ts +21 -0
  12. package/src/charts/chart/variants/RadarChart/RadarChart.tsx +22 -0
  13. package/src/charts/chart/variants/RadarChart/constant.ts +28 -0
  14. package/src/charts/chart/variants/RadarChart/index.ts +1 -0
  15. package/src/charts/chart/variants/ScatterChart/ScatterChart.tsx +23 -0
  16. package/src/charts/chart/variants/ScatterChart/constant.ts +54 -0
  17. package/src/charts/chart/variants/ScatterChart/index.ts +1 -0
  18. package/src/charts/chart/variants/index.ts +3 -0
  19. package/src/charts/index.ts +2 -0
  20. package/src/charts/simpleChart/SimpleChart.tsx +54 -0
  21. package/src/charts/simpleChart/index.ts +1 -0
  22. package/src/components/advancedProgressBar/AdvancedProgressBar.tsx +156 -0
  23. package/src/components/advancedProgressBar/blocks/Bar.tsx +118 -0
  24. package/src/components/advancedProgressBar/blocks/BlockLabel.tsx +49 -0
  25. package/src/components/advancedProgressBar/blocks/Clamp.tsx +85 -0
  26. package/src/components/advancedProgressBar/constants.ts +6 -0
  27. package/src/components/advancedProgressBar/index.ts +2 -0
  28. package/src/components/advancedProgressBar/types/props.ts +69 -0
  29. package/src/components/advancedProgressBar/utils.ts +17 -0
  30. package/src/components/audioPlayback/AudioPlayback.tsx +141 -0
  31. package/src/components/audioPlayback/index.ts +2 -0
  32. package/src/components/audioRecorder/AudioRecorder.tsx +391 -0
  33. package/src/components/audioRecorder/constant/default.ts +19 -0
  34. package/src/components/audioRecorder/constant/labels.ts +9 -0
  35. package/src/components/audioRecorder/index.ts +2 -0
  36. package/src/components/audioRecorder/types/props.ts +56 -0
  37. package/src/components/avatar/Avatar.tsx +132 -0
  38. package/src/components/avatar/index.ts +1 -0
  39. package/src/components/avatar/variants.ts +9 -0
  40. package/src/components/avatarRow/AvatarRow.tsx +127 -0
  41. package/src/components/avatarRow/index.ts +1 -0
  42. package/src/components/breadcrumb/Breadcrumb.tsx +158 -0
  43. package/src/components/breadcrumb/index.ts +1 -0
  44. package/src/components/button/Button.tsx +114 -0
  45. package/src/components/button/index.ts +2 -0
  46. package/src/components/button/variants.ts +41 -0
  47. package/src/components/card/Card.tsx +197 -0
  48. package/src/components/card/index.ts +3 -0
  49. package/src/components/card/variants/CardIcon/CardIcon.tsx +158 -0
  50. package/src/components/card/variants/CardMedia/CardMedia.tsx +127 -0
  51. package/src/components/checkbox/Checkbox.tsx +246 -0
  52. package/src/components/checkbox/index.ts +1 -0
  53. package/src/components/checkbox/variants.ts +13 -0
  54. package/src/components/checkboxGroup/CheckboxGroup.tsx +163 -0
  55. package/src/components/checkboxGroup/index.ts +1 -0
  56. package/src/components/cleenIcon/CleenIcon.tsx +674 -0
  57. package/src/components/cleenIcon/icons/IconAlertCircle.tsx +22 -0
  58. package/src/components/cleenIcon/icons/IconAlertFeatured.tsx +30 -0
  59. package/src/components/cleenIcon/icons/IconAlertOctagon.tsx +21 -0
  60. package/src/components/cleenIcon/icons/IconAlertTriangle.tsx +25 -0
  61. package/src/components/cleenIcon/icons/IconAlignRight.tsx +25 -0
  62. package/src/components/cleenIcon/icons/IconArrowDown.tsx +25 -0
  63. package/src/components/cleenIcon/icons/IconArrowLeft.tsx +25 -0
  64. package/src/components/cleenIcon/icons/IconArrowLeft2.tsx +22 -0
  65. package/src/components/cleenIcon/icons/IconArrowRight.tsx +25 -0
  66. package/src/components/cleenIcon/icons/IconArrowToTop.tsx +20 -0
  67. package/src/components/cleenIcon/icons/IconArrowUp.tsx +22 -0
  68. package/src/components/cleenIcon/icons/IconArrowUpRight.tsx +22 -0
  69. package/src/components/cleenIcon/icons/IconArrowUpRightNarrow.tsx +22 -0
  70. package/src/components/cleenIcon/icons/IconArrowUpRightSquare.tsx +22 -0
  71. package/src/components/cleenIcon/icons/IconAttachment.tsx +22 -0
  72. package/src/components/cleenIcon/icons/IconBarChartSquare.tsx +22 -0
  73. package/src/components/cleenIcon/icons/IconBold.tsx +16 -0
  74. package/src/components/cleenIcon/icons/IconBookmarkCheck.tsx +22 -0
  75. package/src/components/cleenIcon/icons/IconBookmarkCheckFill.tsx +37 -0
  76. package/src/components/cleenIcon/icons/IconBookmarkPlus.tsx +22 -0
  77. package/src/components/cleenIcon/icons/IconBookmarkX.tsx +22 -0
  78. package/src/components/cleenIcon/icons/IconBoxLines.tsx +16 -0
  79. package/src/components/cleenIcon/icons/IconBoxText.tsx +24 -0
  80. package/src/components/cleenIcon/icons/IconBracketsCheck.tsx +25 -0
  81. package/src/components/cleenIcon/icons/IconBracketsEllipses.tsx +22 -0
  82. package/src/components/cleenIcon/icons/IconBuilding.tsx +22 -0
  83. package/src/components/cleenIcon/icons/IconCalendar.tsx +25 -0
  84. package/src/components/cleenIcon/icons/IconCertificateHeart.tsx +25 -0
  85. package/src/components/cleenIcon/icons/IconCheck.tsx +22 -0
  86. package/src/components/cleenIcon/icons/IconCheckCircle.tsx +22 -0
  87. package/src/components/cleenIcon/icons/IconCheckCircleBroken.tsx +25 -0
  88. package/src/components/cleenIcon/icons/IconCheckFill.tsx +45 -0
  89. package/src/components/cleenIcon/icons/IconCheckVerified.tsx +22 -0
  90. package/src/components/cleenIcon/icons/IconChevronDown.tsx +22 -0
  91. package/src/components/cleenIcon/icons/IconChevronLeft.tsx +25 -0
  92. package/src/components/cleenIcon/icons/IconChevronLeftDouble.tsx +22 -0
  93. package/src/components/cleenIcon/icons/IconChevronRight.tsx +25 -0
  94. package/src/components/cleenIcon/icons/IconChevronRightDouble.tsx +22 -0
  95. package/src/components/cleenIcon/icons/IconChevronSelectorVertical.tsx +22 -0
  96. package/src/components/cleenIcon/icons/IconChevronUp.tsx +25 -0
  97. package/src/components/cleenIcon/icons/IconCircleSwap.tsx +22 -0
  98. package/src/components/cleenIcon/icons/IconClockFastForward.tsx +25 -0
  99. package/src/components/cleenIcon/icons/IconClockRewind.tsx +25 -0
  100. package/src/components/cleenIcon/icons/IconClockRewind2.tsx +21 -0
  101. package/src/components/cleenIcon/icons/IconCodeBrowser.tsx +25 -0
  102. package/src/components/cleenIcon/icons/IconCodeCircle.tsx +22 -0
  103. package/src/components/cleenIcon/icons/IconColors.tsx +25 -0
  104. package/src/components/cleenIcon/icons/IconColumnEdit.tsx +19 -0
  105. package/src/components/cleenIcon/icons/IconCopy.tsx +25 -0
  106. package/src/components/cleenIcon/icons/IconCopy2.tsx +22 -0
  107. package/src/components/cleenIcon/icons/IconCopy3.tsx +25 -0
  108. package/src/components/cleenIcon/icons/IconCopy4.tsx +25 -0
  109. package/src/components/cleenIcon/icons/IconCopy5.tsx +25 -0
  110. package/src/components/cleenIcon/icons/IconCopyCheck.tsx +22 -0
  111. package/src/components/cleenIcon/icons/IconCube.tsx +25 -0
  112. package/src/components/cleenIcon/icons/IconCubeOutline.tsx +22 -0
  113. package/src/components/cleenIcon/icons/IconCursorBox.tsx +25 -0
  114. package/src/components/cleenIcon/icons/IconDataflow.tsx +22 -0
  115. package/src/components/cleenIcon/icons/IconDataflow2.tsx +22 -0
  116. package/src/components/cleenIcon/icons/IconDataflow3.tsx +29 -0
  117. package/src/components/cleenIcon/icons/IconDelete.tsx +25 -0
  118. package/src/components/cleenIcon/icons/IconDollarCircle.tsx +25 -0
  119. package/src/components/cleenIcon/icons/IconDotsGrid.tsx +74 -0
  120. package/src/components/cleenIcon/icons/IconDotsHorizontal.tsx +34 -0
  121. package/src/components/cleenIcon/icons/IconDotsVertical.tsx +38 -0
  122. package/src/components/cleenIcon/icons/IconEdit.tsx +25 -0
  123. package/src/components/cleenIcon/icons/IconEditable.tsx +25 -0
  124. package/src/components/cleenIcon/icons/IconExpand.tsx +22 -0
  125. package/src/components/cleenIcon/icons/IconEye.tsx +28 -0
  126. package/src/components/cleenIcon/icons/IconEyeHidden.tsx +25 -0
  127. package/src/components/cleenIcon/icons/IconEyeHidden2.tsx +24 -0
  128. package/src/components/cleenIcon/icons/IconFaceSmile.tsx +24 -0
  129. package/src/components/cleenIcon/icons/IconFilter.tsx +22 -0
  130. package/src/components/cleenIcon/icons/IconFilter2.tsx +22 -0
  131. package/src/components/cleenIcon/icons/IconFlag.tsx +22 -0
  132. package/src/components/cleenIcon/icons/IconFlag2.tsx +25 -0
  133. package/src/components/cleenIcon/icons/IconFlag3.tsx +16 -0
  134. package/src/components/cleenIcon/icons/IconHandShield.tsx +22 -0
  135. package/src/components/cleenIcon/icons/IconHash.tsx +22 -0
  136. package/src/components/cleenIcon/icons/IconHeadsetMic.tsx +21 -0
  137. package/src/components/cleenIcon/icons/IconHeart.tsx +24 -0
  138. package/src/components/cleenIcon/icons/IconHouseLine.tsx +22 -0
  139. package/src/components/cleenIcon/icons/IconImage.tsx +22 -0
  140. package/src/components/cleenIcon/icons/IconImage2.tsx +22 -0
  141. package/src/components/cleenIcon/icons/IconImage3.tsx +17 -0
  142. package/src/components/cleenIcon/icons/IconImage4.tsx +25 -0
  143. package/src/components/cleenIcon/icons/IconImageCheck.tsx +22 -0
  144. package/src/components/cleenIcon/icons/IconInfoCircle.tsx +22 -0
  145. package/src/components/cleenIcon/icons/IconInfoHexagon.tsx +25 -0
  146. package/src/components/cleenIcon/icons/IconItalic.tsx +16 -0
  147. package/src/components/cleenIcon/icons/IconLayersMultiple.tsx +22 -0
  148. package/src/components/cleenIcon/icons/IconLayersSingle.tsx +22 -0
  149. package/src/components/cleenIcon/icons/IconLayout.tsx +22 -0
  150. package/src/components/cleenIcon/icons/IconLayout2.tsx +22 -0
  151. package/src/components/cleenIcon/icons/IconLayoutColumns.tsx +20 -0
  152. package/src/components/cleenIcon/icons/IconLayoutCustom.tsx +16 -0
  153. package/src/components/cleenIcon/icons/IconLayoutSequential.tsx +16 -0
  154. package/src/components/cleenIcon/icons/IconLayoutStuffed.tsx +20 -0
  155. package/src/components/cleenIcon/icons/IconLayoutTile.tsx +16 -0
  156. package/src/components/cleenIcon/icons/IconLifeBuoy.tsx +29 -0
  157. package/src/components/cleenIcon/icons/IconLightbulb.tsx +22 -0
  158. package/src/components/cleenIcon/icons/IconLightning.tsx +22 -0
  159. package/src/components/cleenIcon/icons/IconLightning2.tsx +25 -0
  160. package/src/components/cleenIcon/icons/IconLightningFast.tsx +22 -0
  161. package/src/components/cleenIcon/icons/IconLineChartBar.tsx +22 -0
  162. package/src/components/cleenIcon/icons/IconLineChartBreakoutSquare.tsx +22 -0
  163. package/src/components/cleenIcon/icons/IconLineChartUp.tsx +25 -0
  164. package/src/components/cleenIcon/icons/IconLineChartUp2.tsx +34 -0
  165. package/src/components/cleenIcon/icons/IconLines.tsx +22 -0
  166. package/src/components/cleenIcon/icons/IconLinesCheck.tsx +16 -0
  167. package/src/components/cleenIcon/icons/IconLinesPlay.tsx +23 -0
  168. package/src/components/cleenIcon/icons/IconLink.tsx +25 -0
  169. package/src/components/cleenIcon/icons/IconLink2.tsx +24 -0
  170. package/src/components/cleenIcon/icons/IconLink3.tsx +21 -0
  171. package/src/components/cleenIcon/icons/IconLink4.tsx +17 -0
  172. package/src/components/cleenIcon/icons/IconLink5.tsx +22 -0
  173. package/src/components/cleenIcon/icons/IconListBullet.tsx +18 -0
  174. package/src/components/cleenIcon/icons/IconListOrder.tsx +20 -0
  175. package/src/components/cleenIcon/icons/IconListOrder2.tsx +16 -0
  176. package/src/components/cleenIcon/icons/IconLock.tsx +22 -0
  177. package/src/components/cleenIcon/icons/IconLock2.tsx +22 -0
  178. package/src/components/cleenIcon/icons/IconLogIn.tsx +25 -0
  179. package/src/components/cleenIcon/icons/IconLogOut.tsx +25 -0
  180. package/src/components/cleenIcon/icons/IconLogOut2.tsx +22 -0
  181. package/src/components/cleenIcon/icons/IconMagicWand.tsx +25 -0
  182. package/src/components/cleenIcon/icons/IconMagicWand2.tsx +22 -0
  183. package/src/components/cleenIcon/icons/IconMail.tsx +25 -0
  184. package/src/components/cleenIcon/icons/IconMessageSquare.tsx +25 -0
  185. package/src/components/cleenIcon/icons/IconMessageSquare2.tsx +22 -0
  186. package/src/components/cleenIcon/icons/IconMessageXSquare.tsx +25 -0
  187. package/src/components/cleenIcon/icons/IconMinusCircle.tsx +22 -0
  188. package/src/components/cleenIcon/icons/IconMobile.tsx +25 -0
  189. package/src/components/cleenIcon/icons/IconMonitor.tsx +22 -0
  190. package/src/components/cleenIcon/icons/IconMonitor2.tsx +25 -0
  191. package/src/components/cleenIcon/icons/IconMonitor3.tsx +25 -0
  192. package/src/components/cleenIcon/icons/IconMoonCircle.tsx +28 -0
  193. package/src/components/cleenIcon/icons/IconNavigationPointer.tsx +22 -0
  194. package/src/components/cleenIcon/icons/IconNotificationBox.tsx +22 -0
  195. package/src/components/cleenIcon/icons/IconPCSetup.tsx +22 -0
  196. package/src/components/cleenIcon/icons/IconPalette.tsx +40 -0
  197. package/src/components/cleenIcon/icons/IconPasscodeLock.tsx +25 -0
  198. package/src/components/cleenIcon/icons/IconPencil.tsx +25 -0
  199. package/src/components/cleenIcon/icons/IconPercentageCircle.tsx +29 -0
  200. package/src/components/cleenIcon/icons/IconPerspective.tsx +22 -0
  201. package/src/components/cleenIcon/icons/IconPhoneCall.tsx +25 -0
  202. package/src/components/cleenIcon/icons/IconPin.tsx +22 -0
  203. package/src/components/cleenIcon/icons/IconPlayCircle.tsx +28 -0
  204. package/src/components/cleenIcon/icons/IconPlus.tsx +22 -0
  205. package/src/components/cleenIcon/icons/IconPlusCircle.tsx +25 -0
  206. package/src/components/cleenIcon/icons/IconPulse.tsx +25 -0
  207. package/src/components/cleenIcon/icons/IconQuestionCircle.tsx +24 -0
  208. package/src/components/cleenIcon/icons/IconRadioButton.tsx +27 -0
  209. package/src/components/cleenIcon/icons/IconRadioButtonActive.tsx +39 -0
  210. package/src/components/cleenIcon/icons/IconReceiptCheck.tsx +25 -0
  211. package/src/components/cleenIcon/icons/IconRedo.tsx +16 -0
  212. package/src/components/cleenIcon/icons/IconRefresh.tsx +22 -0
  213. package/src/components/cleenIcon/icons/IconRefresh2.tsx +22 -0
  214. package/src/components/cleenIcon/icons/IconRefresh3.tsx +20 -0
  215. package/src/components/cleenIcon/icons/IconRepeat.tsx +22 -0
  216. package/src/components/cleenIcon/icons/IconRepeat2.tsx +22 -0
  217. package/src/components/cleenIcon/icons/IconRetweet.tsx +33 -0
  218. package/src/components/cleenIcon/icons/IconRoundChart.tsx +25 -0
  219. package/src/components/cleenIcon/icons/IconRoundChart2.tsx +29 -0
  220. package/src/components/cleenIcon/icons/IconRoute.tsx +22 -0
  221. package/src/components/cleenIcon/icons/IconSave.tsx +25 -0
  222. package/src/components/cleenIcon/icons/IconSave2.tsx +22 -0
  223. package/src/components/cleenIcon/icons/IconScanDots.tsx +22 -0
  224. package/src/components/cleenIcon/icons/IconSearch.tsx +22 -0
  225. package/src/components/cleenIcon/icons/IconSend.tsx +25 -0
  226. package/src/components/cleenIcon/icons/IconSettings.tsx +32 -0
  227. package/src/components/cleenIcon/icons/IconSettings2.tsx +25 -0
  228. package/src/components/cleenIcon/icons/IconSettings3.tsx +22 -0
  229. package/src/components/cleenIcon/icons/IconShieldLightning.tsx +22 -0
  230. package/src/components/cleenIcon/icons/IconShieldPlus.tsx +22 -0
  231. package/src/components/cleenIcon/icons/IconShieldRemove.tsx +16 -0
  232. package/src/components/cleenIcon/icons/IconShuffle.tsx +25 -0
  233. package/src/components/cleenIcon/icons/IconSlashCircle.tsx +22 -0
  234. package/src/components/cleenIcon/icons/IconSlashOctagon.tsx +22 -0
  235. package/src/components/cleenIcon/icons/IconSocialGlobe.tsx +23 -0
  236. package/src/components/cleenIcon/icons/IconSocialLinkedin.tsx +21 -0
  237. package/src/components/cleenIcon/icons/IconSocialX.tsx +28 -0
  238. package/src/components/cleenIcon/icons/IconSpeedometer.tsx +22 -0
  239. package/src/components/cleenIcon/icons/IconStairsRound.tsx +21 -0
  240. package/src/components/cleenIcon/icons/IconStar.tsx +22 -0
  241. package/src/components/cleenIcon/icons/IconStarHalf.tsx +39 -0
  242. package/src/components/cleenIcon/icons/IconStars.tsx +28 -0
  243. package/src/components/cleenIcon/icons/IconStars2.tsx +29 -0
  244. package/src/components/cleenIcon/icons/IconStrikethrough.tsx +16 -0
  245. package/src/components/cleenIcon/icons/IconSuccessFeatured.tsx +30 -0
  246. package/src/components/cleenIcon/icons/IconSun.tsx +22 -0
  247. package/src/components/cleenIcon/icons/IconSwitchHorizontal.tsx +22 -0
  248. package/src/components/cleenIcon/icons/IconTag.tsx +22 -0
  249. package/src/components/cleenIcon/icons/IconTarget.tsx +21 -0
  250. package/src/components/cleenIcon/icons/IconTarget2.tsx +34 -0
  251. package/src/components/cleenIcon/icons/IconTextFormat.tsx +17 -0
  252. package/src/components/cleenIcon/icons/IconTextFormat2.tsx +22 -0
  253. package/src/components/cleenIcon/icons/IconTextHighlight.tsx +16 -0
  254. package/src/components/cleenIcon/icons/IconTranslate.tsx +25 -0
  255. package/src/components/cleenIcon/icons/IconTrash.tsx +25 -0
  256. package/src/components/cleenIcon/icons/IconTrending.tsx +22 -0
  257. package/src/components/cleenIcon/icons/IconUnderline.tsx +16 -0
  258. package/src/components/cleenIcon/icons/IconUndo.tsx +22 -0
  259. package/src/components/cleenIcon/icons/IconUndo2.tsx +16 -0
  260. package/src/components/cleenIcon/icons/IconUploadCloud.tsx +22 -0
  261. package/src/components/cleenIcon/icons/IconUser.tsx +22 -0
  262. package/src/components/cleenIcon/icons/IconUserEdit.tsx +25 -0
  263. package/src/components/cleenIcon/icons/IconUserRight.tsx +22 -0
  264. package/src/components/cleenIcon/icons/IconUserSquare.tsx +25 -0
  265. package/src/components/cleenIcon/icons/IconUsers.tsx +25 -0
  266. package/src/components/cleenIcon/icons/IconUsersUp.tsx +25 -0
  267. package/src/components/cleenIcon/icons/IconVolume.tsx +25 -0
  268. package/src/components/cleenIcon/icons/IconWrench.tsx +22 -0
  269. package/src/components/cleenIcon/icons/IconX.tsx +25 -0
  270. package/src/components/cleenIcon/icons/IconXCircle.tsx +22 -0
  271. package/src/components/cleenIcon/icons/IconXCircle2.tsx +42 -0
  272. package/src/components/cleenIcon/icons/IconXClose.tsx +25 -0
  273. package/src/components/cleenIcon/icons/IconXSquare.tsx +22 -0
  274. package/src/components/cleenIcon/icons/index.ts +215 -0
  275. package/src/components/cleenIcon/index.ts +4 -0
  276. package/src/components/cleenIcon/types/icon.ts +226 -0
  277. package/src/components/collapsible/Collapsible.tsx +148 -0
  278. package/src/components/collapsible/index.ts +5 -0
  279. package/src/components/creditCardInput/CreditCardInput.tsx +236 -0
  280. package/src/components/creditCardInput/index.ts +2 -0
  281. package/src/components/creditCardInput/types/card.ts +13 -0
  282. package/src/components/creditCardInput/types/props.ts +44 -0
  283. package/src/components/creditCardInput/util/format.ts +102 -0
  284. package/src/components/datePicker/DatePicker.tsx +235 -0
  285. package/src/components/datePicker/index.ts +2 -0
  286. package/src/components/datePicker/types/props.ts +47 -0
  287. package/src/components/datePicker/utils/date.ts +40 -0
  288. package/src/components/divider/Divider.tsx +43 -0
  289. package/src/components/divider/index.ts +1 -0
  290. package/src/components/drawer/Drawer.tsx +222 -0
  291. package/src/components/drawer/index.ts +1 -0
  292. package/src/components/dropdown/Dropdown.tsx +224 -0
  293. package/src/components/dropdown/index.ts +1 -0
  294. package/src/components/filterDrawer/FilterDrawer.tsx +147 -0
  295. package/src/components/filterDrawer/blocks/FilterDrawerFooter.tsx +119 -0
  296. package/src/components/filterDrawer/blocks/SaveFilterStep.tsx +56 -0
  297. package/src/components/filterDrawer/blocks/SavedFilterRow.tsx +166 -0
  298. package/src/components/filterDrawer/blocks/SavedFiltersDropdown.tsx +142 -0
  299. package/src/components/filterDrawer/constants/filter.ts +4 -0
  300. package/src/components/filterDrawer/constants/labels.ts +52 -0
  301. package/src/components/filterDrawer/constants/tab.ts +7 -0
  302. package/src/components/filterDrawer/context/context.ts +28 -0
  303. package/src/components/filterDrawer/context/provider.tsx +50 -0
  304. package/src/components/filterDrawer/index.ts +7 -0
  305. package/src/components/filterDrawer/types/filters.ts +28 -0
  306. package/src/components/filterDrawer/types/props.ts +107 -0
  307. package/src/components/filterDrawer/types/validation.ts +6 -0
  308. package/src/components/formGroup/FormGroup.tsx +165 -0
  309. package/src/components/formGroup/index.ts +1 -0
  310. package/src/components/groupSelector/GroupSelector.tsx +729 -0
  311. package/src/components/groupSelector/index.ts +6 -0
  312. package/src/components/index.ts +44 -0
  313. package/src/components/infoLabels/InfoLabels.tsx +88 -0
  314. package/src/components/infoLabels/index.ts +1 -0
  315. package/src/components/input/Input.tsx +269 -0
  316. package/src/components/input/index.ts +1 -0
  317. package/src/components/loader/Loader.tsx +91 -0
  318. package/src/components/loader/index.ts +1 -0
  319. package/src/components/lookup/Lookup.tsx +433 -0
  320. package/src/components/lookup/blocks/LookupOptionList.tsx +130 -0
  321. package/src/components/lookup/index.ts +2 -0
  322. package/src/components/lookup/types/lookup.ts +97 -0
  323. package/src/components/menu/Menu.tsx +103 -0
  324. package/src/components/menu/blocks/MenuContent.tsx +105 -0
  325. package/src/components/menu/blocks/MenuItem.tsx +120 -0
  326. package/src/components/menu/index.ts +2 -0
  327. package/src/components/menu/types/menu.ts +30 -0
  328. package/src/components/menu/types/menuItem.ts +48 -0
  329. package/src/components/modal/Modal.tsx +191 -0
  330. package/src/components/modal/index.ts +1 -0
  331. package/src/components/notification/Notification.tsx +79 -0
  332. package/src/components/notification/constant/notification.ts +30 -0
  333. package/src/components/notification/index.ts +2 -0
  334. package/src/components/notification/wrappers/CleenNotificationContainer.tsx +9 -0
  335. package/src/components/pagination/Pagination.tsx +294 -0
  336. package/src/components/pagination/blocks/PaginationGoToPage.tsx +91 -0
  337. package/src/components/pagination/blocks/PaginationPageSize.tsx +145 -0
  338. package/src/components/pagination/constants/labels.ts +15 -0
  339. package/src/components/pagination/index.ts +9 -0
  340. package/src/components/pillBadge/PillBadge.tsx +130 -0
  341. package/src/components/pillBadge/helper.ts +11 -0
  342. package/src/components/pillBadge/index.ts +1 -0
  343. package/src/components/pillBadge/variants.ts +47 -0
  344. package/src/components/popover/Popover.tsx +108 -0
  345. package/src/components/popover/index.ts +2 -0
  346. package/src/components/popover/types/popover.ts +21 -0
  347. package/src/components/progressBar/ProgressBar.tsx +179 -0
  348. package/src/components/progressBar/index.ts +1 -0
  349. package/src/components/progressCircle/ProgressCircle.tsx +142 -0
  350. package/src/components/progressCircle/index.ts +1 -0
  351. package/src/components/radioBoxGroup/RadioBoxGroup.tsx +207 -0
  352. package/src/components/radioBoxGroup/index.ts +1 -0
  353. package/src/components/radioButtonGroup/RadioButtonGroup.tsx +208 -0
  354. package/src/components/radioButtonGroup/blocks/RadioButton.tsx +22 -0
  355. package/src/components/radioButtonGroup/index.ts +4 -0
  356. package/src/components/radioButtonGroup/types/radioButton.ts +10 -0
  357. package/src/components/rangeSlider/RangeSlider.tsx +366 -0
  358. package/src/components/rangeSlider/index.ts +1 -0
  359. package/src/components/select/Select.tsx +349 -0
  360. package/src/components/select/blocks/SelectCustomMenuList.tsx +70 -0
  361. package/src/components/select/blocks/SelectNoOptionsMessage.tsx +22 -0
  362. package/src/components/select/blocks/SelectOption.tsx +19 -0
  363. package/src/components/select/blocks/SelectSingleValue.tsx +28 -0
  364. package/src/components/select/index.ts +1 -0
  365. package/src/components/sidebar/Sidebar.tsx +210 -0
  366. package/src/components/sidebar/SidebarItem.tsx +88 -0
  367. package/src/components/sidebar/drawerContainer/DrawerContainer.tsx +36 -0
  368. package/src/components/sidebar/drawerContainer/DrawerContentTitle.tsx +165 -0
  369. package/src/components/sidebar/drawerContainer/index.ts +2 -0
  370. package/src/components/sidebar/index.ts +13 -0
  371. package/src/components/sidebar/types.ts +157 -0
  372. package/src/components/skeletons/blocks/Skeleton.tsx +72 -0
  373. package/src/components/skeletons/blocks/SkeletonAvatar.tsx +43 -0
  374. package/src/components/skeletons/blocks/SkeletonBadge.tsx +30 -0
  375. package/src/components/skeletons/blocks/SkeletonBanner.tsx +44 -0
  376. package/src/components/skeletons/blocks/SkeletonButton.tsx +31 -0
  377. package/src/components/skeletons/blocks/SkeletonCard.tsx +39 -0
  378. package/src/components/skeletons/blocks/SkeletonCard2.tsx +57 -0
  379. package/src/components/skeletons/blocks/SkeletonCard3.tsx +89 -0
  380. package/src/components/skeletons/blocks/SkeletonCardStack.tsx +22 -0
  381. package/src/components/skeletons/blocks/SkeletonChart.tsx +114 -0
  382. package/src/components/skeletons/blocks/SkeletonContentCard.tsx +75 -0
  383. package/src/components/skeletons/blocks/SkeletonDataGrid.tsx +73 -0
  384. package/src/components/skeletons/blocks/SkeletonForm.tsx +50 -0
  385. package/src/components/skeletons/blocks/SkeletonImage.tsx +45 -0
  386. package/src/components/skeletons/blocks/SkeletonInfoCard.tsx +130 -0
  387. package/src/components/skeletons/blocks/SkeletonInput.tsx +32 -0
  388. package/src/components/skeletons/blocks/SkeletonList.tsx +67 -0
  389. package/src/components/skeletons/blocks/SkeletonParagraph.tsx +52 -0
  390. package/src/components/skeletons/blocks/SkeletonText.tsx +22 -0
  391. package/src/components/skeletons/blocks/SkeletonVideo.tsx +71 -0
  392. package/src/components/skeletons/blocks/SkeletonWidgetCard.tsx +56 -0
  393. package/src/components/skeletons/blocks/SkeletonWrapper.tsx +140 -0
  394. package/src/components/skeletons/index.ts +24 -0
  395. package/src/components/skeletons/styles/skeleton.ts +2 -0
  396. package/src/components/skeletons/types/skeleton.ts +8 -0
  397. package/src/components/slider/Slider.tsx +298 -0
  398. package/src/components/slider/index.ts +1 -0
  399. package/src/components/stepper/Stepper.tsx +185 -0
  400. package/src/components/stepper/index.ts +1 -0
  401. package/src/components/switch/Switch.tsx +152 -0
  402. package/src/components/switch/index.ts +1 -0
  403. package/src/components/tabs/Tabs.tsx +140 -0
  404. package/src/components/tabs/index.ts +2 -0
  405. package/src/components/tabs/types/tab.ts +33 -0
  406. package/src/components/tabs/variants.ts +49 -0
  407. package/src/components/textArea/TextArea.tsx +244 -0
  408. package/src/components/textArea/index.ts +1 -0
  409. package/src/components/tooltip/Tooltip.tsx +200 -0
  410. package/src/components/tooltip/index.ts +1 -0
  411. package/src/icons/IconFromLibrary.tsx +13 -0
  412. package/src/icons/getIconByName.ts +81 -0
  413. package/src/icons/index.ts +16 -0
  414. package/src/index.ts +1 -0
  415. package/tsconfig.json +27 -0
  416. package/tsup.config.ts +23 -0
@@ -0,0 +1,729 @@
1
+ import {
2
+ cn,
3
+ useDebounce,
4
+ useOutsideClick,
5
+ usePositionClose,
6
+ type Position,
7
+ } from '@cleen/ui-core';
8
+ import React, {
9
+ useEffect,
10
+ useMemo,
11
+ useRef,
12
+ useState,
13
+ type ComponentProps,
14
+ type CSSProperties,
15
+ type JSX,
16
+ } from 'react';
17
+ import { createPortal } from 'react-dom';
18
+ import { Button } from '../button';
19
+ import {
20
+ IconChevronDown,
21
+ IconChevronUp,
22
+ IconDotsVertical,
23
+ IconPlusCircle,
24
+ } from '../cleenIcon';
25
+ import { Divider } from '../divider';
26
+ import { Input } from '../input';
27
+ import { Loader } from '../loader';
28
+ import { Menu } from '../menu';
29
+ import { PillBadge } from '../pillBadge';
30
+
31
+ function isObject(value: unknown): value is Record<string, unknown> {
32
+ return value !== null && typeof value === 'object';
33
+ }
34
+
35
+ function getProp<T = unknown>(obj: unknown, key: string): T | undefined {
36
+ if (!isObject(obj)) return undefined;
37
+ if (!(key in obj)) return undefined;
38
+ return (obj as Record<string, unknown>)[key] as T;
39
+ }
40
+
41
+ function getArrayProp<T = unknown>(obj: unknown, key: string): T[] {
42
+ const v = getProp<unknown>(obj, key);
43
+ if (Array.isArray(v)) return v as T[];
44
+ return [];
45
+ }
46
+
47
+ export interface GroupSelectorSaveResult {
48
+ success: boolean;
49
+ [k: string]: unknown;
50
+ }
51
+
52
+ export interface LabelsProps extends ComponentProps<'div'> {
53
+ inputPlaceholder?: string;
54
+ newGroupPlaceholder?: string;
55
+ newItemPlaceholder?: string;
56
+ saveButtonLabel?: string;
57
+ }
58
+
59
+ export interface GroupSelectorThreeDotOption<T = unknown> {
60
+ label: string;
61
+ icon?: React.ReactElement;
62
+ onClick: (target: T) => void;
63
+ disabledOptionCallback?: (target: T) => boolean;
64
+ }
65
+
66
+ export interface GroupSelectorProps<G = unknown, I = unknown> {
67
+ position?: Position;
68
+ labels?: LabelsProps;
69
+ groups?: G[] | null;
70
+ selectedItemID?: string | number | null;
71
+ groupThreeDotMenuOptions?: GroupSelectorThreeDotOption<G>[];
72
+ itemThreeDotMenuOptions?: GroupSelectorThreeDotOption<I>[];
73
+ refetchData?: () => Promise<void> | void;
74
+ onGroupSave?: (
75
+ payload: Record<string, unknown>
76
+ ) => Promise<GroupSelectorSaveResult>;
77
+ onItemSave?: (
78
+ payload: Record<string, unknown>
79
+ ) => Promise<GroupSelectorSaveResult>;
80
+ onGroupThreeDotMenuClick?: (group: G | null) => void;
81
+ onItemThreeDotMenuClick?: (item: I | null) => void;
82
+ onSearchChange?: (searchText: string) => void;
83
+ onItemSelect?: (item: I | null) => void;
84
+ groupIDKey: string;
85
+ groupTitleKey: string;
86
+ itemsKey: string;
87
+ itemIDKey: string;
88
+ itemGroupIDKey: string;
89
+ itemTitleKey: string;
90
+ itemSubtitleKey?: string;
91
+ newValueMinLength?: number;
92
+ isLoading?: boolean;
93
+ isGroupSaving?: boolean;
94
+ isItemSaving?: boolean;
95
+ selectedColor?: string;
96
+ className?: string;
97
+ classNames?: {
98
+ container?: string;
99
+ label?: string;
100
+ input?: string;
101
+ columnsContainer?: string;
102
+ leftColumn?: string;
103
+ rightColumn?: string;
104
+ groupItem?: string;
105
+ groupItemTitle?: string;
106
+ newGroupButton?: string;
107
+ item?: string;
108
+ itemTitle?: string;
109
+ itemSubtitle?: string;
110
+ newItemButton?: string;
111
+ };
112
+ style?: CSSProperties;
113
+ styles?: {
114
+ container?: CSSProperties;
115
+ label?: CSSProperties;
116
+ input?: CSSProperties;
117
+ columnsContainer?: CSSProperties;
118
+ leftColumn?: CSSProperties;
119
+ rightColumn?: CSSProperties;
120
+ groupItem?: CSSProperties;
121
+ groupItemTitle?: CSSProperties;
122
+ newGroupButton?: CSSProperties;
123
+ item?: CSSProperties;
124
+ itemTitle?: CSSProperties;
125
+ itemSubtitle?: CSSProperties;
126
+ newItemButton?: CSSProperties;
127
+ };
128
+ }
129
+
130
+ /**
131
+ * The `GroupSelector` component renders a two-column searchable panel for browsing and selecting items
132
+ * that are organised into labelled groups.
133
+ *
134
+ * - The left column lists groups; selecting one reveals its items in the right column.
135
+ * - Both columns support an inline "add new" input and a three-dot context menu per entry.
136
+ * - Key mapping props (`groupIDKey`, `groupTitleKey`, `itemsKey`, `itemIDKey`, `itemGroupIDKey`,
137
+ * `itemTitleKey`, `itemSubtitleKey`) let you use any plain object shape for groups and items.
138
+ * - `selectedItemID` highlights the currently active item.
139
+ * - `onItemSelect` is fired when the user picks an item; `onGroupSave`/`onItemSave` handle creation.
140
+ * - Use `isLoading`, `isGroupSaving`, `isItemSaving` to show loader states during async operations.
141
+ * - Accepts `classNames` and `styles` for granular visual customisation of every element.
142
+ */
143
+ export const GroupSelector = <G = unknown, I = unknown>({
144
+ position = 'bottom-right',
145
+ labels,
146
+ groups = [],
147
+ selectedItemID = null,
148
+ groupThreeDotMenuOptions = [],
149
+ itemThreeDotMenuOptions = [],
150
+ refetchData,
151
+ onGroupSave,
152
+ onItemSave,
153
+ onGroupThreeDotMenuClick,
154
+ onItemThreeDotMenuClick,
155
+ onSearchChange,
156
+ onItemSelect,
157
+ groupIDKey,
158
+ groupTitleKey,
159
+ itemsKey,
160
+ itemIDKey,
161
+ itemGroupIDKey,
162
+ itemTitleKey,
163
+ itemSubtitleKey,
164
+ newValueMinLength = 2,
165
+ isLoading = false,
166
+ isGroupSaving = false,
167
+ isItemSaving = false,
168
+ selectedColor = 'rgb(var(--cleen-primary), 0.1)',
169
+ className,
170
+ classNames,
171
+ style,
172
+ styles,
173
+ }: GroupSelectorProps<G, I>): JSX.Element => {
174
+ const [isOpen, setIsOpen] = useState(false);
175
+ const [isAbleToCreateNewGroup, setIsAbleToCreateNewGroup] = useState(false);
176
+ const [isAbleToCreateNewItem, setIsAbleToCreateNewItem] = useState(false);
177
+ const [selectedGroupID, setSelectedGroupID] = useState<
178
+ string | number | null
179
+ >(null);
180
+ const [selectedItem, setSelectedItem] = useState<I | null>(null);
181
+ const [newGroupTitle, setNewGroupTitle] = useState('');
182
+ const [newItemTitle, setNewItemTitle] = useState('');
183
+ const [searchText, setSearchText] = useState('');
184
+ const [debouncedSearch] = useDebounce(searchText, 500);
185
+
186
+ const selectorRef = useRef<HTMLDivElement | null>(null);
187
+ const columnsRef = useRef<HTMLDivElement | null>(null);
188
+
189
+ // Calculate optimal position for the selector dropdown
190
+ const { positionStyles, isMounted } = usePositionClose({
191
+ triggerRef: selectorRef,
192
+ targetRef: columnsRef,
193
+ position,
194
+ isOpen,
195
+ offset: 10,
196
+ });
197
+
198
+ useOutsideClick({
199
+ refs: [columnsRef],
200
+ handler: () => setIsOpen(false),
201
+ enabled: isOpen,
202
+ });
203
+
204
+ const safeGroups = useMemo(() => groups ?? [], [groups]);
205
+
206
+ const groupMap = useMemo(() => {
207
+ const map = new Map<string | number, I[]>();
208
+ for (const g of safeGroups) {
209
+ const gid = getProp<string | number>(g, groupIDKey);
210
+ if (gid != null) map.set(gid, getArrayProp<I>(g, itemsKey));
211
+ }
212
+ return map;
213
+ }, [safeGroups, groupIDKey, itemsKey]);
214
+
215
+ const items = useMemo(() => {
216
+ if (selectedGroupID == null) {
217
+ return Array.from(groupMap?.values()).flat();
218
+ }
219
+ return groupMap?.get(selectedGroupID) ?? [];
220
+ }, [selectedGroupID, groupMap]);
221
+
222
+ useEffect(() => {
223
+ if (selectedItemID == null) {
224
+ setSelectedItem(null);
225
+ setSelectedGroupID(null);
226
+ return;
227
+ }
228
+
229
+ const allItems = Array.from(groupMap?.values())?.flat();
230
+ const found = allItems?.find(
231
+ it => getProp(it, itemIDKey) === selectedItemID
232
+ );
233
+
234
+ if (found) {
235
+ const gid = getProp<string | number>(found, itemGroupIDKey) ?? null;
236
+ setSelectedItem(found);
237
+ setSelectedGroupID(gid);
238
+ } else {
239
+ setSelectedItem(null);
240
+ setSelectedGroupID(null);
241
+ }
242
+ }, [selectedItemID, groupMap, itemIDKey, itemGroupIDKey]);
243
+
244
+ useEffect(() => {
245
+ if (onSearchChange) void onSearchChange(debouncedSearch ?? '');
246
+ }, [debouncedSearch, onSearchChange]);
247
+
248
+ useEffect(() => {
249
+ if (!isOpen) {
250
+ setIsAbleToCreateNewGroup(false);
251
+ setIsAbleToCreateNewItem(false);
252
+ setNewGroupTitle('');
253
+ setNewItemTitle('');
254
+ }
255
+ }, [isOpen]);
256
+
257
+ const handleGroupClick = (gid: string | number | null) => {
258
+ if (gid === selectedGroupID) {
259
+ setSelectedGroupID(null);
260
+ setSelectedItem(null);
261
+ onItemSelect?.(null);
262
+ } else {
263
+ setSelectedItem(null);
264
+ setSelectedGroupID(gid);
265
+ onItemSelect?.(null);
266
+ }
267
+ };
268
+
269
+ const handleItemClick = (item: I) => {
270
+ const gidRaw = getProp(item, itemGroupIDKey);
271
+ const gid =
272
+ typeof gidRaw === 'string' || typeof gidRaw === 'number' ? gidRaw : null;
273
+
274
+ setSelectedGroupID(gid);
275
+ setSelectedItem(item);
276
+ onItemSelect?.(item);
277
+ setIsOpen(false);
278
+ };
279
+
280
+ async function handleNewGroup() {
281
+ if (!onGroupSave) return;
282
+ const payload: Record<string, unknown> = {
283
+ [groupTitleKey]: newGroupTitle,
284
+ };
285
+ try {
286
+ const res = await onGroupSave(payload);
287
+ if (res?.success) {
288
+ setIsAbleToCreateNewGroup(false);
289
+ setNewGroupTitle('');
290
+ if (refetchData) await refetchData();
291
+ }
292
+ } catch {
293
+ // swallow — parent can handle notifications
294
+ }
295
+ }
296
+
297
+ async function handleNewItem() {
298
+ if (!onItemSave) return;
299
+ const payload: Record<string, unknown> = {
300
+ [itemTitleKey]: newItemTitle,
301
+ ...(selectedGroupID != null ? { [itemGroupIDKey]: selectedGroupID } : {}),
302
+ };
303
+ try {
304
+ const res = await onItemSave(payload);
305
+ if (res?.success) {
306
+ setIsAbleToCreateNewItem(false);
307
+ setNewItemTitle('');
308
+ if (refetchData) await refetchData();
309
+ }
310
+ } catch {
311
+ // swallow — parent can handle notifications
312
+ }
313
+ }
314
+
315
+ return (
316
+ <div className={cn('cleen', className)} style={style}>
317
+ <div
318
+ ref={selectorRef}
319
+ className={cn(
320
+ 'cleen-relative cleen-w-full cleen-cursor-pointer',
321
+ classNames?.container
322
+ )}
323
+ style={styles?.container}
324
+ onClick={e => {
325
+ e.stopPropagation();
326
+ setIsOpen(true);
327
+ }}
328
+ >
329
+ <Input
330
+ placeholder={labels?.inputPlaceholder}
331
+ rightIcon={
332
+ isOpen ? (
333
+ <IconChevronUp className="cleen-w-5 cleen-h-5 cleen-text-gray/30" />
334
+ ) : (
335
+ <IconChevronDown className="cleen-w-5 cleen-h-5 cleen-text-gray/30" />
336
+ )
337
+ }
338
+ value={searchText}
339
+ onChange={e => {
340
+ setSelectedGroupID(null);
341
+ setSelectedItem(null);
342
+ setSearchText(e.target.value);
343
+ }}
344
+ classNames={{
345
+ input: isOpen ? '' : 'cleen-cursor-pointer',
346
+ }}
347
+ className={classNames?.input}
348
+ style={styles?.input}
349
+ />
350
+
351
+ {isOpen &&
352
+ createPortal(
353
+ <div className="cleen">
354
+ <div
355
+ ref={columnsRef}
356
+ className={cn(
357
+ 'cleen-overflow-hidden cleen-flex cleen-items-start cleen-justify-start cleen-w-[500px] cleen-h-[344px] cleen-bg-white cleen-border cleen-border-gray/10 cleen-rounded-lg cleen-shadow-xl cleen-cursor-default',
358
+ 'cleen-fixed cleen-z-50',
359
+ {
360
+ 'cleen-opacity-0': !isMounted,
361
+ },
362
+ classNames?.columnsContainer
363
+ )}
364
+ style={{
365
+ top: `${positionStyles.top}px`,
366
+ left: `${positionStyles.left}px`,
367
+ ...styles?.columnsContainer,
368
+ }}
369
+ >
370
+ <div className="cleen-w-1/2 cleen-h-full">
371
+ <div
372
+ className={cn(
373
+ 'cleen-overflow-scroll cleen-no-scrollbar cleen-flex cleen-flex-col cleen-items-start cleen-justify-start cleen-w-full cleen-h-[300px]',
374
+ classNames?.leftColumn
375
+ )}
376
+ style={styles?.leftColumn}
377
+ >
378
+ {isLoading ? (
379
+ <div className="cleen-flex cleen-items-center cleen-justify-center cleen-w-full cleen-h-full">
380
+ <Loader size="sm" />
381
+ </div>
382
+ ) : (
383
+ groups?.map((group, idx) => {
384
+ const gid = getProp<string | number>(group, groupIDKey);
385
+ const isSelected = gid === selectedGroupID;
386
+ const groupTitle = String(
387
+ getProp(group, groupTitleKey) ?? ''
388
+ );
389
+ const itemsCount =
390
+ getArrayProp(group, itemsKey)?.length ?? 0;
391
+
392
+ return (
393
+ <div
394
+ key={`group-${idx}-${String(gid ?? idx)}`}
395
+ className={cn(
396
+ 'cleen-group cleen-flex cleen-items-center cleen-justify-between cleen-gap-2 cleen-px-3 cleen-w-full cleen-min-h-10 cleen-cursor-pointer hover:cleen-bg-primary/10',
397
+ classNames?.groupItem
398
+ )}
399
+ style={{
400
+ ...(styles?.groupItem || {}),
401
+ ...(isSelected
402
+ ? { backgroundColor: selectedColor }
403
+ : {}),
404
+ }}
405
+ onClick={e => {
406
+ e.stopPropagation();
407
+ e.preventDefault();
408
+ handleGroupClick(gid ?? null);
409
+ }}
410
+ >
411
+ <div
412
+ className={cn(
413
+ 'cleen-flex cleen-items-center cleen-justify-start cleen-gap-2',
414
+ groupThreeDotMenuOptions?.length > 0
415
+ ? 'cleen-w-[calc(100%-30px)]'
416
+ : 'cleen-w-full'
417
+ )}
418
+ >
419
+ <span
420
+ className={cn(
421
+ 'cleen-truncate cleen-font-semibold cleen-text-[14px] cleen-text-gray/90',
422
+ classNames?.groupItemTitle
423
+ )}
424
+ style={styles?.groupItemTitle}
425
+ >
426
+ {groupTitle}
427
+ </span>
428
+ <PillBadge
429
+ color="lighter-blue"
430
+ label={itemsCount}
431
+ />
432
+ </div>
433
+ {groupThreeDotMenuOptions?.length > 0 && (
434
+ <div
435
+ className="cleen-opacity-0 group-hover:cleen-opacity-100"
436
+ onClick={e => {
437
+ e.stopPropagation();
438
+ onGroupThreeDotMenuClick?.(group);
439
+ }}
440
+ >
441
+ <Menu
442
+ position="bottom-right"
443
+ keepOpenOnClick={false}
444
+ items={groupThreeDotMenuOptions?.map(
445
+ option => {
446
+ const isOptionDisabled =
447
+ option?.disabledOptionCallback?.(group);
448
+
449
+ return {
450
+ ...option,
451
+ type: 'button' as const,
452
+ label: (
453
+ <span className="cleen-font-semibold cleen-text-[14px] cleen-text-gray/70">
454
+ {option?.label}
455
+ </span>
456
+ ),
457
+ onClick: () => {
458
+ if (!isOptionDisabled) {
459
+ option?.onClick(group);
460
+ }
461
+ },
462
+ disabled: isOptionDisabled,
463
+ };
464
+ }
465
+ )}
466
+ classNames={{
467
+ menu: 'cleen-min-w-max',
468
+ }}
469
+ className="cleen-flex cleen-items-center cleen-justify-center cleen-w-5 cleen-h-5 cleen-bg-white cleen-rounded-md"
470
+ >
471
+ <IconDotsVertical className="cleen-w-4 cleen-h-4 cleen-text-gray/70 cleen-cursor-pointer hover:cleen-text-primary" />
472
+ </Menu>
473
+ </div>
474
+ )}
475
+ </div>
476
+ );
477
+ })
478
+ )}
479
+ </div>
480
+ <Divider isHorizontal />
481
+ {isAbleToCreateNewGroup ? (
482
+ <div className="cleen-flex cleen-items-center cleen-justify-between cleen-w-full cleen-h-10">
483
+ <Input
484
+ leftIcon={
485
+ <IconPlusCircle className="cleen-w-4 cleen-h-4 cleen-text-gray/30" />
486
+ }
487
+ placeholder={labels?.newGroupPlaceholder}
488
+ value={newGroupTitle}
489
+ onChange={e => setNewGroupTitle(e.target.value)}
490
+ classNames={{
491
+ inputContainer: 'cleen-border-none',
492
+ input: 'cleen-w-full',
493
+ }}
494
+ className="cleen-w-[170px]"
495
+ autoFocus
496
+ />
497
+ <div className="cleen-flex cleen-items-center cleen-justify-center cleen-w-[80px] cleen-h-full">
498
+ {onGroupSave ? (
499
+ isGroupSaving ? (
500
+ <Loader />
501
+ ) : newGroupTitle?.length > newValueMinLength ? (
502
+ <Button
503
+ variant="primary"
504
+ label={labels?.saveButtonLabel}
505
+ onClick={() => {
506
+ void handleNewGroup();
507
+ }}
508
+ classNames={{
509
+ container: 'cleen-w-max cleen-h-7',
510
+ }}
511
+ />
512
+ ) : (
513
+ <div />
514
+ )
515
+ ) : (
516
+ <div />
517
+ )}
518
+ </div>
519
+ </div>
520
+ ) : (
521
+ <div
522
+ className={cn(
523
+ 'cleen-flex cleen-items-center cleen-justify-start cleen-gap-2 cleen-w-full cleen-px-2 cleen-h-10 cleen-cursor-pointer hover:cleen-bg-primary/10',
524
+ classNames?.newGroupButton
525
+ )}
526
+ style={styles?.newGroupButton}
527
+ onClick={() => setIsAbleToCreateNewGroup(true)}
528
+ >
529
+ <IconPlusCircle className="cleen-w-4 cleen-h-4 cleen-text-gray/30" />
530
+ <span className="cleen-text-normal cleen-text-[14px] cleen-text-gray/50">
531
+ {labels?.newGroupPlaceholder}
532
+ </span>
533
+ </div>
534
+ )}
535
+ </div>
536
+ <Divider className="cleen-absolute cleen-top-0 cleen-left-1/2 cleen-min-w-[1px] cleen-h-full cleen-bg-gray/10 cleen-z-[1]" />
537
+ <div className="cleen-w-1/2 cleen-h-full">
538
+ <div
539
+ className={cn(
540
+ 'cleen-overflow-scroll cleen-no-scrollbar cleen-flex cleen-flex-col cleen-items-start cleen-justify-start cleen-w-full cleen-h-[300px]',
541
+ classNames?.rightColumn
542
+ )}
543
+ style={styles?.rightColumn}
544
+ >
545
+ {isLoading ? (
546
+ <div className="cleen-flex cleen-items-center cleen-justify-center cleen-w-full cleen-h-full">
547
+ <Loader size="sm" />
548
+ </div>
549
+ ) : (
550
+ items?.map((item, idx) => {
551
+ const tid = getProp(item, itemIDKey);
552
+ const isSelected =
553
+ selectedItem &&
554
+ getProp(selectedItem, itemIDKey) === tid;
555
+ const title = String(getProp(item, itemTitleKey) ?? '');
556
+ const subtitle = itemSubtitleKey
557
+ ? String(getProp(item, itemSubtitleKey) ?? '')
558
+ : '';
559
+
560
+ return (
561
+ <div
562
+ key={`item-${idx}-${String(tid ?? idx)}`}
563
+ className={cn(
564
+ 'cleen-group cleen-flex cleen-items-center cleen-justify-between cleen-gap-2 cleen-px-3 cleen-w-full cleen-min-h-[60px] cleen-cursor-pointer hover:cleen-bg-primary/10',
565
+ classNames?.item
566
+ )}
567
+ style={{
568
+ ...(styles?.item || {}),
569
+ ...(isSelected
570
+ ? { backgroundColor: selectedColor }
571
+ : {}),
572
+ }}
573
+ onClick={e => {
574
+ e.stopPropagation();
575
+ e.preventDefault();
576
+ handleItemClick(item);
577
+ }}
578
+ >
579
+ <div
580
+ className={cn(
581
+ 'cleen-flex cleen-flex-col cleen-items-start cleen-justify-center',
582
+ itemThreeDotMenuOptions?.length > 0
583
+ ? 'cleen-w-[calc(100%-30px)]'
584
+ : 'cleen-w-full'
585
+ )}
586
+ >
587
+ <span
588
+ className={cn(
589
+ 'cleen-truncate cleen-w-full cleen-font-semibold cleen-text-[14px] cleen-text-gray/90',
590
+ classNames?.itemTitle
591
+ )}
592
+ style={styles?.itemTitle}
593
+ >
594
+ {title}
595
+ </span>
596
+ <span
597
+ className={cn(
598
+ 'cleen-truncate cleen-w-full cleen-font-semibold cleen-text-[12px] cleen-text-gray/50',
599
+ classNames?.itemSubtitle
600
+ )}
601
+ style={styles?.itemSubtitle}
602
+ >
603
+ {subtitle}
604
+ </span>
605
+ </div>
606
+ {itemThreeDotMenuOptions?.length > 0 && (
607
+ <div
608
+ className="cleen-opacity-0 group-hover:cleen-opacity-100"
609
+ onClick={e => {
610
+ e.stopPropagation();
611
+ onItemThreeDotMenuClick?.(item);
612
+ }}
613
+ >
614
+ <Menu
615
+ position="bottom-right"
616
+ keepOpenOnClick={false}
617
+ items={itemThreeDotMenuOptions?.map(
618
+ option => {
619
+ const isOptionDisabled =
620
+ option?.disabledOptionCallback?.(item);
621
+
622
+ return {
623
+ ...option,
624
+ type: 'button' as const,
625
+ label: (
626
+ <span className="cleen-font-semibold cleen-text-[14px] cleen-text-gray/70">
627
+ {option?.label}
628
+ </span>
629
+ ),
630
+ onClick: () => {
631
+ if (!isOptionDisabled) {
632
+ option?.onClick(item);
633
+ }
634
+ },
635
+ disabled: isOptionDisabled,
636
+ };
637
+ }
638
+ )}
639
+ classNames={{
640
+ menu: 'cleen-min-w-max',
641
+ }}
642
+ className="cleen-flex cleen-items-center cleen-justify-center cleen-w-5 cleen-h-5 cleen-bg-white cleen-rounded-md"
643
+ >
644
+ <IconDotsVertical className="cleen-w-4 cleen-h-4 cleen-text-gray/70 cleen-cursor-pointer hover:cleen-text-primary" />
645
+ </Menu>
646
+ </div>
647
+ )}
648
+ </div>
649
+ );
650
+ })
651
+ )}
652
+ </div>
653
+ <Divider isHorizontal />
654
+ {isAbleToCreateNewItem ? (
655
+ <div className="cleen-flex cleen-items-center cleen-justify-between cleen-w-full cleen-h-10">
656
+ <Input
657
+ leftIcon={
658
+ <IconPlusCircle className="cleen-w-4 cleen-h-4 cleen-text-gray/30" />
659
+ }
660
+ placeholder={labels?.newItemPlaceholder}
661
+ value={newItemTitle}
662
+ onChange={e => setNewItemTitle(e.target.value)}
663
+ classNames={{
664
+ inputContainer: 'cleen-border-none',
665
+ input: 'cleen-w-full',
666
+ }}
667
+ className="cleen-w-[170px]"
668
+ autoFocus
669
+ />
670
+ <div className="cleen-flex cleen-items-center cleen-justify-center cleen-w-[80px] cleen-h-full">
671
+ {onItemSave ? (
672
+ isItemSaving ? (
673
+ <Loader />
674
+ ) : newItemTitle?.length > newValueMinLength ? (
675
+ <Button
676
+ variant="primary"
677
+ label={labels?.saveButtonLabel}
678
+ onClick={() => {
679
+ void handleNewItem();
680
+ }}
681
+ classNames={{
682
+ container: 'cleen-w-max cleen-h-7',
683
+ }}
684
+ />
685
+ ) : (
686
+ <div />
687
+ )
688
+ ) : (
689
+ <div />
690
+ )}
691
+ </div>
692
+ </div>
693
+ ) : (
694
+ <div
695
+ className={cn(
696
+ 'cleen-flex cleen-items-center cleen-justify-start cleen-gap-2 cleen-w-full cleen-px-2 cleen-h-10 cleen-cursor-pointer hover:cleen-bg-primary/10',
697
+ classNames?.newItemButton
698
+ )}
699
+ style={styles?.newItemButton}
700
+ onClick={() => setIsAbleToCreateNewItem(true)}
701
+ >
702
+ <IconPlusCircle className="cleen-w-4 cleen-h-4 cleen-text-gray/30" />
703
+ <span className="cleen-text-normal cleen-text-[14px] cleen-text-gray/50">
704
+ {labels?.newItemPlaceholder}
705
+ </span>
706
+ </div>
707
+ )}
708
+ </div>
709
+ </div>
710
+ </div>,
711
+ document.body
712
+ )}
713
+
714
+ {!isOpen && selectedItem && (
715
+ <div
716
+ className="cleen-absolute cleen-top-1.5 cleen-left-1 cleen-flex cleen-items-center cleen-justify-start cleen-pl-2.5 cleen-w-[calc(100%-40px)] cleen-h-8 cleen-bg-white"
717
+ onClick={() => setIsOpen(true)}
718
+ >
719
+ <span className="cleen-truncate cleen-font-semibold cleen-text-[14px] cleen-text-gray/70">
720
+ {String(getProp<unknown>(selectedItem, itemTitleKey) ?? '')}
721
+ </span>
722
+ </div>
723
+ )}
724
+ </div>
725
+ </div>
726
+ );
727
+ };
728
+
729
+ export default GroupSelector;