@xjur-ui/react 1.0.6 → 2.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 (336) hide show
  1. package/.turbo/turbo-build.log +279 -68
  2. package/CHANGELOG.md +114 -0
  3. package/README.md +146 -0
  4. package/dist/chunk-2CM3SFOY.js +2 -0
  5. package/dist/chunk-2CM3SFOY.js.map +1 -0
  6. package/dist/chunk-2CTBH6VI.js +2 -0
  7. package/dist/chunk-2CTBH6VI.js.map +1 -0
  8. package/dist/chunk-4BGTC333.js +2 -0
  9. package/dist/chunk-4BGTC333.js.map +1 -0
  10. package/dist/chunk-5WLIDYZH.js +2 -0
  11. package/dist/chunk-5WLIDYZH.js.map +1 -0
  12. package/dist/chunk-6AD6O6II.js +2 -0
  13. package/dist/chunk-6AD6O6II.js.map +1 -0
  14. package/dist/chunk-AA6V5YEC.js +2 -0
  15. package/dist/chunk-AA6V5YEC.js.map +1 -0
  16. package/dist/chunk-BK6FP63A.js +2 -0
  17. package/dist/chunk-BK6FP63A.js.map +1 -0
  18. package/dist/chunk-BZDGWC5O.js +2 -0
  19. package/dist/chunk-BZDGWC5O.js.map +1 -0
  20. package/dist/chunk-CBFC4QME.js +2 -0
  21. package/dist/chunk-CBFC4QME.js.map +1 -0
  22. package/dist/chunk-CI3ZXWEX.js +2 -0
  23. package/dist/chunk-CI3ZXWEX.js.map +1 -0
  24. package/dist/chunk-DFXHNK5D.js +2 -0
  25. package/dist/chunk-DFXHNK5D.js.map +1 -0
  26. package/dist/chunk-EIG6CBTQ.js +2 -0
  27. package/dist/chunk-EIG6CBTQ.js.map +1 -0
  28. package/dist/chunk-EXC2XOL6.js +2 -0
  29. package/dist/chunk-EXC2XOL6.js.map +1 -0
  30. package/dist/chunk-F4DYKYWJ.js +2 -0
  31. package/dist/chunk-F4DYKYWJ.js.map +1 -0
  32. package/dist/chunk-F5ZLEQGN.js +2 -0
  33. package/dist/chunk-F5ZLEQGN.js.map +1 -0
  34. package/dist/chunk-IKL6PSXU.js +2 -0
  35. package/dist/chunk-IKL6PSXU.js.map +1 -0
  36. package/dist/chunk-IRHU7PDO.js +2 -0
  37. package/dist/chunk-IRHU7PDO.js.map +1 -0
  38. package/dist/chunk-J4X5RQTR.js +2 -0
  39. package/dist/chunk-J4X5RQTR.js.map +1 -0
  40. package/dist/chunk-KIFR5VIE.js +2 -0
  41. package/dist/chunk-KIFR5VIE.js.map +1 -0
  42. package/dist/chunk-KS6WGBHQ.js +2 -0
  43. package/dist/chunk-KS6WGBHQ.js.map +1 -0
  44. package/dist/chunk-L4ET6GIZ.js +2 -0
  45. package/dist/chunk-L4ET6GIZ.js.map +1 -0
  46. package/dist/chunk-MZSV4LNY.js +2 -0
  47. package/dist/chunk-MZSV4LNY.js.map +1 -0
  48. package/dist/chunk-NELCN6E2.js +2 -0
  49. package/dist/chunk-NELCN6E2.js.map +1 -0
  50. package/dist/chunk-OS53BV63.js +3 -0
  51. package/dist/chunk-OS53BV63.js.map +1 -0
  52. package/dist/chunk-PKCW37CJ.js +2 -0
  53. package/dist/chunk-PKCW37CJ.js.map +1 -0
  54. package/dist/chunk-RWMV7APX.js +2 -0
  55. package/dist/chunk-RWMV7APX.js.map +1 -0
  56. package/dist/chunk-SLAAEXWI.js +2 -0
  57. package/dist/chunk-SLAAEXWI.js.map +1 -0
  58. package/dist/chunk-SXGSWVMZ.js +2 -0
  59. package/dist/chunk-SXGSWVMZ.js.map +1 -0
  60. package/dist/chunk-TB6KI6CL.js +2 -0
  61. package/dist/chunk-TB6KI6CL.js.map +1 -0
  62. package/dist/chunk-TSVURBUY.js +2 -0
  63. package/dist/chunk-TSVURBUY.js.map +1 -0
  64. package/dist/chunk-UXIVZWLB.js +2 -0
  65. package/dist/chunk-UXIVZWLB.js.map +1 -0
  66. package/dist/chunk-WEBAXQID.js +2 -0
  67. package/dist/chunk-WEBAXQID.js.map +1 -0
  68. package/dist/chunk-WV7QV2PU.js +2 -0
  69. package/dist/chunk-WV7QV2PU.js.map +1 -0
  70. package/dist/chunk-Z47R2CIM.js +2 -0
  71. package/dist/chunk-Z47R2CIM.js.map +1 -0
  72. package/dist/chunk-ZVVPUP7V.js +2 -0
  73. package/dist/chunk-ZVVPUP7V.js.map +1 -0
  74. package/dist/components/avatar-group.js +2 -179
  75. package/dist/components/avatar-group.js.map +1 -0
  76. package/dist/components/avatar.js +2 -59
  77. package/dist/components/avatar.js.map +1 -0
  78. package/dist/components/badge.js +2 -111
  79. package/dist/components/badge.js.map +1 -0
  80. package/dist/components/breadcrumb.d.ts +20 -0
  81. package/dist/components/breadcrumb.js +2 -0
  82. package/dist/components/breadcrumb.js.map +1 -0
  83. package/dist/components/chip.d.ts +5 -2
  84. package/dist/components/chip.js +2 -256
  85. package/dist/components/chip.js.map +1 -0
  86. package/dist/components/collapsible.js +2 -41
  87. package/dist/components/collapsible.js.map +1 -0
  88. package/dist/components/dialog.d.ts +51 -0
  89. package/dist/components/dialog.js +2 -0
  90. package/dist/components/dialog.js.map +1 -0
  91. package/dist/components/divider.js +2 -29
  92. package/dist/components/divider.js.map +1 -0
  93. package/dist/components/drag-and-drop/drag-handle.d.ts +15 -0
  94. package/dist/components/drag-and-drop/drag-handle.js +2 -0
  95. package/dist/components/drag-and-drop/drag-handle.js.map +1 -0
  96. package/dist/components/drag-and-drop/drag-list-item.d.ts +14 -0
  97. package/dist/components/drag-and-drop/drag-list-item.js +2 -0
  98. package/dist/components/drag-and-drop/drag-list-item.js.map +1 -0
  99. package/dist/components/drag-and-drop/drag-list.d.ts +14 -0
  100. package/dist/components/drag-and-drop/drag-list.js +2 -0
  101. package/dist/components/drag-and-drop/drag-list.js.map +1 -0
  102. package/dist/components/drag-and-drop/drag-root.d.ts +6 -0
  103. package/dist/components/drag-and-drop/drag-root.js +2 -0
  104. package/dist/components/drag-and-drop/drag-root.js.map +1 -0
  105. package/dist/components/drag-and-drop/index.d.ts +10 -0
  106. package/dist/components/drag-and-drop/index.js +2 -0
  107. package/dist/components/drag-and-drop/index.js.map +1 -0
  108. package/dist/components/drag-and-drop/types/drag-item.d.ts +9 -0
  109. package/dist/components/drag-and-drop/types/drag-item.js +2 -0
  110. package/dist/components/drag-and-drop/types/drag-item.js.map +1 -0
  111. package/dist/components/dropdown-menu.js +2 -295
  112. package/dist/components/dropdown-menu.js.map +1 -0
  113. package/dist/components/form/button.js +2 -0
  114. package/dist/components/form/button.js.map +1 -0
  115. package/dist/components/form/calendar.js +2 -0
  116. package/dist/components/form/calendar.js.map +1 -0
  117. package/dist/components/form/checkbox.js +2 -0
  118. package/dist/components/form/checkbox.js.map +1 -0
  119. package/dist/components/form/context/field.context.d.ts +15 -0
  120. package/dist/components/form/context/field.context.js +2 -0
  121. package/dist/components/form/context/field.context.js.map +1 -0
  122. package/dist/components/form/date-picker.d.ts +84 -0
  123. package/dist/components/form/date-picker.js +2 -0
  124. package/dist/components/form/date-picker.js.map +1 -0
  125. package/dist/components/form/floating-label.d.ts +6 -0
  126. package/dist/components/form/floating-label.js +2 -0
  127. package/dist/components/form/floating-label.js.map +1 -0
  128. package/dist/components/form/input.d.ts +95 -0
  129. package/dist/components/form/input.js +2 -0
  130. package/dist/components/form/input.js.map +1 -0
  131. package/dist/components/form/otp-input.js +2 -0
  132. package/dist/components/form/otp-input.js.map +1 -0
  133. package/dist/components/form/radio.js +2 -0
  134. package/dist/components/form/radio.js.map +1 -0
  135. package/dist/components/{rich-editor.d.ts → form/rich-editor.d.ts} +2 -1
  136. package/dist/components/form/rich-editor.js +2 -0
  137. package/dist/components/form/rich-editor.js.map +1 -0
  138. package/dist/components/form/search-input.js +2 -0
  139. package/dist/components/form/search-input.js.map +1 -0
  140. package/dist/components/form/select.d.ts +94 -0
  141. package/dist/components/form/select.js +2 -0
  142. package/dist/components/form/select.js.map +1 -0
  143. package/dist/components/form/switch.js +2 -0
  144. package/dist/components/form/switch.js.map +1 -0
  145. package/dist/components/full-calendar/calendar-add-event.d.ts +9 -0
  146. package/dist/components/full-calendar/calendar-add-event.js +2 -0
  147. package/dist/components/full-calendar/calendar-add-event.js.map +1 -0
  148. package/dist/components/full-calendar/calendar-body.d.ts +6 -0
  149. package/dist/components/full-calendar/calendar-body.js +2 -0
  150. package/dist/components/full-calendar/calendar-body.js.map +1 -0
  151. package/dist/components/full-calendar/calendar-cell.d.ts +11 -0
  152. package/dist/components/full-calendar/calendar-cell.js +2 -0
  153. package/dist/components/full-calendar/calendar-cell.js.map +1 -0
  154. package/dist/components/full-calendar/calendar-day-view.d.ts +5 -0
  155. package/dist/components/full-calendar/calendar-day-view.js +2 -0
  156. package/dist/components/full-calendar/calendar-day-view.js.map +1 -0
  157. package/dist/components/full-calendar/calendar-event.d.ts +18 -0
  158. package/dist/components/full-calendar/calendar-event.js +2 -0
  159. package/dist/components/full-calendar/calendar-event.js.map +1 -0
  160. package/dist/components/full-calendar/calendar-header.d.ts +6 -0
  161. package/dist/components/full-calendar/calendar-header.js +2 -0
  162. package/dist/components/full-calendar/calendar-header.js.map +1 -0
  163. package/dist/components/full-calendar/calendar-month-view.d.ts +5 -0
  164. package/dist/components/full-calendar/calendar-month-view.js +2 -0
  165. package/dist/components/full-calendar/calendar-month-view.js.map +1 -0
  166. package/dist/components/full-calendar/calendar-more-events-dropdown.d.ts +9 -0
  167. package/dist/components/full-calendar/calendar-more-events-dropdown.js +2 -0
  168. package/dist/components/full-calendar/calendar-more-events-dropdown.js.map +1 -0
  169. package/dist/components/full-calendar/calendar-navigator.d.ts +5 -0
  170. package/dist/components/full-calendar/calendar-navigator.js +2 -0
  171. package/dist/components/full-calendar/calendar-navigator.js.map +1 -0
  172. package/dist/components/full-calendar/calendar-root.d.ts +30 -0
  173. package/dist/components/full-calendar/calendar-root.js +2 -0
  174. package/dist/components/full-calendar/calendar-root.js.map +1 -0
  175. package/dist/components/full-calendar/calendar-today-button.d.ts +9 -0
  176. package/dist/components/full-calendar/calendar-today-button.js +2 -0
  177. package/dist/components/full-calendar/calendar-today-button.js.map +1 -0
  178. package/dist/components/full-calendar/calendar-toggle-view.d.ts +5 -0
  179. package/dist/components/full-calendar/calendar-toggle-view.js +2 -0
  180. package/dist/components/full-calendar/calendar-toggle-view.js.map +1 -0
  181. package/dist/components/full-calendar/calendar-view-renderer.d.ts +5 -0
  182. package/dist/components/full-calendar/calendar-view-renderer.js +2 -0
  183. package/dist/components/full-calendar/calendar-view-renderer.js.map +1 -0
  184. package/dist/components/full-calendar/calendar-week-day.d.ts +10 -0
  185. package/dist/components/full-calendar/calendar-week-day.js +2 -0
  186. package/dist/components/full-calendar/calendar-week-day.js.map +1 -0
  187. package/dist/components/full-calendar/calendar-week-view.d.ts +5 -0
  188. package/dist/components/full-calendar/calendar-week-view.js +2 -0
  189. package/dist/components/full-calendar/calendar-week-view.js.map +1 -0
  190. package/dist/components/full-calendar/helpers/calendar.d.ts +25 -0
  191. package/dist/components/full-calendar/helpers/calendar.js +2 -0
  192. package/dist/components/full-calendar/helpers/calendar.js.map +1 -0
  193. package/dist/components/full-calendar/index.d.ts +18 -0
  194. package/dist/components/full-calendar/index.js +2 -0
  195. package/dist/components/full-calendar/index.js.map +1 -0
  196. package/dist/components/full-calendar/types/calendar-cell.d.ts +6 -0
  197. package/dist/components/full-calendar/types/calendar-cell.js +2 -0
  198. package/dist/components/full-calendar/types/calendar-cell.js.map +1 -0
  199. package/dist/components/full-calendar/types/calendar-event.d.ts +8 -0
  200. package/dist/components/full-calendar/types/calendar-event.js +2 -0
  201. package/dist/components/full-calendar/types/calendar-event.js.map +1 -0
  202. package/dist/components/full-calendar/types/calendar-view.d.ts +3 -0
  203. package/dist/components/full-calendar/types/calendar-view.js +2 -0
  204. package/dist/components/full-calendar/types/calendar-view.js.map +1 -0
  205. package/dist/components/full-calendar/types/calendar-week-hour.d.ts +6 -0
  206. package/dist/components/full-calendar/types/calendar-week-hour.js +2 -0
  207. package/dist/components/full-calendar/types/calendar-week-hour.js.map +1 -0
  208. package/dist/components/horizontal-scroll.d.ts +11 -0
  209. package/dist/components/horizontal-scroll.js +2 -0
  210. package/dist/components/horizontal-scroll.js.map +1 -0
  211. package/dist/components/icon.d.ts +3 -4
  212. package/dist/components/icon.js +2 -177
  213. package/dist/components/icon.js.map +1 -0
  214. package/dist/components/list.js +2 -179
  215. package/dist/components/list.js.map +1 -0
  216. package/dist/components/logo.js +2 -324
  217. package/dist/components/logo.js.map +1 -0
  218. package/dist/components/selection-bar.d.ts +57 -0
  219. package/dist/components/selection-bar.js +2 -0
  220. package/dist/components/selection-bar.js.map +1 -0
  221. package/dist/components/sheet.d.ts +8 -8
  222. package/dist/components/sheet.js +2 -251
  223. package/dist/components/sheet.js.map +1 -0
  224. package/dist/components/skeleton.js +2 -16
  225. package/dist/components/skeleton.js.map +1 -0
  226. package/dist/components/status.js +2 -111
  227. package/dist/components/status.js.map +1 -0
  228. package/dist/components/table.js +2 -196
  229. package/dist/components/table.js.map +1 -0
  230. package/dist/components/tabs.d.ts +9 -6
  231. package/dist/components/tabs.js +2 -54
  232. package/dist/components/tabs.js.map +1 -0
  233. package/dist/components/tag.d.ts +5 -2
  234. package/dist/components/tag.js +2 -189
  235. package/dist/components/tag.js.map +1 -0
  236. package/dist/components/tooltip.js +2 -58
  237. package/dist/components/tooltip.js.map +1 -0
  238. package/dist/components/typography.js +2 -78
  239. package/dist/components/typography.js.map +1 -0
  240. package/dist/components/upload.d.ts +74 -0
  241. package/dist/components/upload.js +2 -0
  242. package/dist/components/upload.js.map +1 -0
  243. package/dist/hooks/index.d.ts +7 -0
  244. package/dist/hooks/index.js +2 -0
  245. package/dist/hooks/index.js.map +1 -0
  246. package/dist/icons-CmDuL0gZ.d.ts +4 -0
  247. package/dist/index.css +2 -2322
  248. package/dist/index.css.map +1 -0
  249. package/dist/logo-PQRZORCS.js +3 -0
  250. package/dist/logo-PQRZORCS.js.map +1 -0
  251. package/package.json +60 -18
  252. package/src/components/breadcrumb.tsx +119 -0
  253. package/src/components/chip.tsx +11 -3
  254. package/src/components/dialog.tsx +242 -0
  255. package/src/components/drag-and-drop/drag-handle.tsx +46 -0
  256. package/src/components/drag-and-drop/drag-list-item.tsx +91 -0
  257. package/src/components/drag-and-drop/drag-list.tsx +47 -0
  258. package/src/components/drag-and-drop/drag-root.tsx +30 -0
  259. package/src/components/drag-and-drop/index.ts +39 -0
  260. package/src/components/drag-and-drop/types/drag-item.ts +7 -0
  261. package/src/components/{calendar.tsx → form/calendar.tsx} +9 -8
  262. package/src/components/{checkbox.tsx → form/checkbox.tsx} +2 -2
  263. package/src/components/form/context/field.context.ts +27 -0
  264. package/src/components/form/date-picker.tsx +199 -0
  265. package/src/components/form/floating-label.tsx +60 -0
  266. package/src/components/form/input.tsx +235 -0
  267. package/src/components/{radio.tsx → form/radio.tsx} +1 -1
  268. package/src/components/{rich-editor.tsx → form/rich-editor.tsx} +10 -9
  269. package/src/components/{search-input.tsx → form/search-input.tsx} +2 -2
  270. package/src/components/form/select.tsx +274 -0
  271. package/src/components/full-calendar/calendar-add-event.tsx +15 -0
  272. package/src/components/full-calendar/calendar-body.tsx +12 -0
  273. package/src/components/full-calendar/calendar-cell.tsx +120 -0
  274. package/src/components/full-calendar/calendar-day-view.tsx +76 -0
  275. package/src/components/full-calendar/calendar-event.tsx +178 -0
  276. package/src/components/full-calendar/calendar-header.tsx +14 -0
  277. package/src/components/full-calendar/calendar-month-view.tsx +69 -0
  278. package/src/components/full-calendar/calendar-more-events-dropdown.tsx +39 -0
  279. package/src/components/full-calendar/calendar-navigator.tsx +86 -0
  280. package/src/components/full-calendar/calendar-root.tsx +165 -0
  281. package/src/components/full-calendar/calendar-today-button.tsx +21 -0
  282. package/src/components/full-calendar/calendar-toggle-view.tsx +61 -0
  283. package/src/components/full-calendar/calendar-view-renderer.tsx +19 -0
  284. package/src/components/full-calendar/calendar-week-day.tsx +49 -0
  285. package/src/components/full-calendar/calendar-week-view.tsx +88 -0
  286. package/src/components/full-calendar/helpers/calendar.ts +158 -0
  287. package/src/components/full-calendar/index.ts +16 -0
  288. package/src/components/full-calendar/types/calendar-cell.ts +4 -0
  289. package/src/components/full-calendar/types/calendar-event.ts +7 -0
  290. package/src/components/full-calendar/types/calendar-view.ts +1 -0
  291. package/src/components/full-calendar/types/calendar-week-hour.ts +4 -0
  292. package/src/components/horizontal-scroll.tsx +159 -0
  293. package/src/components/icon.tsx +1 -1
  294. package/src/components/logo.tsx +25 -20
  295. package/src/components/selection-bar.tsx +273 -0
  296. package/src/components/sheet.tsx +2 -2
  297. package/src/components/tabs.tsx +56 -37
  298. package/src/components/tag.tsx +11 -3
  299. package/src/components/upload.tsx +647 -0
  300. package/src/index.css +2 -2
  301. package/src/resources/icons.ts +4 -1
  302. package/src/resources/logo/index.tsx +33 -0
  303. package/tsup.config.ts +23 -5
  304. package/dist/components/button.js +0 -98
  305. package/dist/components/calendar.js +0 -751
  306. package/dist/components/checkbox.js +0 -153
  307. package/dist/components/date-picker.d.ts +0 -20
  308. package/dist/components/date-picker.js +0 -232
  309. package/dist/components/input.d.ts +0 -32
  310. package/dist/components/input.js +0 -315
  311. package/dist/components/otp-input.js +0 -47
  312. package/dist/components/radio.js +0 -156
  313. package/dist/components/rich-editor.js +0 -723
  314. package/dist/components/search-input.js +0 -274
  315. package/dist/components/select.d.ts +0 -33
  316. package/dist/components/select.js +0 -550
  317. package/dist/components/switch.js +0 -36
  318. package/dist/components/test.d.ts +0 -5
  319. package/dist/components/test.js +0 -8
  320. package/dist/index.js +0 -0
  321. package/src/components/date-picker.tsx +0 -160
  322. package/src/components/input.tsx +0 -256
  323. package/src/components/select.tsx +0 -240
  324. package/src/components/test.tsx +0 -3
  325. package/src/index.ts +0 -1
  326. package/src/resources/logo/index.ts +0 -3
  327. /package/dist/components/{button.d.ts → form/button.d.ts} +0 -0
  328. /package/dist/components/{calendar.d.ts → form/calendar.d.ts} +0 -0
  329. /package/dist/components/{checkbox.d.ts → form/checkbox.d.ts} +0 -0
  330. /package/dist/components/{otp-input.d.ts → form/otp-input.d.ts} +0 -0
  331. /package/dist/components/{radio.d.ts → form/radio.d.ts} +0 -0
  332. /package/dist/components/{search-input.d.ts → form/search-input.d.ts} +0 -0
  333. /package/dist/components/{switch.d.ts → form/switch.d.ts} +0 -0
  334. /package/src/components/{button.tsx → form/button.tsx} +0 -0
  335. /package/src/components/{otp-input.tsx → form/otp-input.tsx} +0 -0
  336. /package/src/components/{switch.tsx → form/switch.tsx} +0 -0
@@ -0,0 +1,274 @@
1
+ import { tv, twJoin, twMerge } from '@xjur-ui/util'
2
+ import { useMemo, type ComponentProps } from 'react'
3
+ import * as RadixPopover from '@radix-ui/react-popover'
4
+ import { Icon, type IconType } from '../icon'
5
+ import { Typography } from '../typography'
6
+ import {
7
+ ListHeaderTitle,
8
+ ListHeader,
9
+ ListContent,
10
+ ListItem,
11
+ ListRoot
12
+ } from '../list'
13
+ import {
14
+ FieldContext,
15
+ useFieldContext,
16
+ type FieldContextValue
17
+ } from './context/field.context'
18
+ import { FloatingLabel } from './floating-label'
19
+
20
+ export const select = tv({
21
+ slots: {
22
+ wrapper: 'group flex w-full flex-col gap-small-2x',
23
+ trigger: [
24
+ 'h-large-4x w-full cursor-pointer relative',
25
+ 'flex items-center gap-small rounded-small-1x justify-between',
26
+ 'py-small_1x-alt px-small',
27
+ 'bg-layer-2-idle border border-border-layer-2',
28
+ 'group-has-[div[data-slot=input-action-slot]]:rounded-r-none',
29
+ 'transition-all duration-200'
30
+ ],
31
+ content: [
32
+ 'group z-10 max-h-[var(--radix-popover-content-available-height)] max-w-[var(--radix-popover-content-available-width)] min-w-[var(--radix-popover-trigger-width)]'
33
+ ],
34
+ icon: 'size-large text-icon-neutral-3 flex items-center justify-center',
35
+ slotText:
36
+ 'size-large flex items-center justify-center !text-size-label-md text-neutral-placeholder',
37
+ caption: '!text-size-body-sm font-normal'
38
+ },
39
+ variants: {
40
+ state: {
41
+ normal: {
42
+ trigger:
43
+ 'hover:border-border-layer-3 data-[state=open]:border-primary-idle data-[state=open]:hover:border-primary-idle'
44
+ },
45
+ error: {
46
+ trigger:
47
+ 'border-danger-idle hover:border-danger-idle data-[state=open]:border-danger-idle data-[state=open]:hover:border-danger-idle',
48
+ caption: 'text-danger-label-idle'
49
+ },
50
+ disabled: {
51
+ trigger: 'pointer-events-none border-transparent bg-layer-2-idle'
52
+ }
53
+ }
54
+ }
55
+ })
56
+
57
+ const { wrapper, trigger, icon, caption, slotText, content } = select()
58
+
59
+ export function SelectRoot({
60
+ className,
61
+ state = 'normal',
62
+ defaultOpen,
63
+ variant = 'normal',
64
+ modal,
65
+ open,
66
+ onOpenChange: handleOpenChange,
67
+ ...props
68
+ }: ComponentProps<'div'> &
69
+ FieldContextValue &
70
+ ComponentProps<typeof RadixPopover.Root>) {
71
+ return (
72
+ <RadixPopover.Root
73
+ defaultOpen={defaultOpen}
74
+ modal={modal}
75
+ open={open}
76
+ onOpenChange={handleOpenChange}
77
+ >
78
+ <FieldContext.Provider value={{ state, variant }}>
79
+ <div className={wrapper({ className, state })} {...props} />
80
+ </FieldContext.Provider>
81
+ </RadixPopover.Root>
82
+ )
83
+ }
84
+
85
+ export function SelectTrigger({
86
+ className,
87
+ ...props
88
+ }: ComponentProps<typeof RadixPopover.Trigger>) {
89
+ const { state, variant } = useFieldContext()
90
+
91
+ const filterTrigger = tv({
92
+ base: ['group bg-layer-2-idle'],
93
+ variants: {
94
+ state: {
95
+ normal: [
96
+ 'border-border-layer-2 hover:border-border-layer-3 has-[input:not(:placeholder-shown)]:border-primary-idle'
97
+ ],
98
+ error: ['border-danger-idle hover:border-danger-idle'],
99
+ disabled: ['border border-border-layer-2 opacity-60']
100
+ }
101
+ }
102
+ })
103
+
104
+ const mergedClassName = twMerge(
105
+ trigger({ state, className }),
106
+ variant === 'filter' && filterTrigger({ state, className })
107
+ )
108
+
109
+ return (
110
+ <RadixPopover.Trigger
111
+ className={mergedClassName}
112
+ disabled={state === 'disabled'}
113
+ {...props}
114
+ />
115
+ )
116
+ }
117
+
118
+ export function SelectIcon({
119
+ className,
120
+ name,
121
+ ...props
122
+ }: ComponentProps<'div'> & {
123
+ name: IconType
124
+ }) {
125
+ const { state } = useFieldContext()
126
+
127
+ return (
128
+ <div className={icon({ className, state })} {...props}>
129
+ <Icon name={name} />
130
+ </div>
131
+ )
132
+ }
133
+
134
+ export function SelectLabel(props: ComponentProps<typeof FloatingLabel>) {
135
+ return <FloatingLabel {...props} />
136
+ }
137
+
138
+ export function SelectValue({
139
+ className,
140
+ displayValue = '',
141
+ value,
142
+ placeholder,
143
+ ...props
144
+ }: ComponentProps<'input'> & { displayValue?: string }) {
145
+ const { variant } = useFieldContext()
146
+
147
+ const valueOrPlaceholder = useMemo(() => {
148
+ if (variant === 'filter') return displayValue
149
+ return displayValue || placeholder
150
+ }, [displayValue, placeholder, variant])
151
+
152
+ return (
153
+ <div className="flex w-full">
154
+ <Typography className="text-neutral-dark group-has-[div[data-slot=date-picker-left-slot]]:pl-large-1x">
155
+ {valueOrPlaceholder}
156
+ </Typography>
157
+
158
+ <input
159
+ {...props}
160
+ aria-readonly={true}
161
+ className={twJoin('pointer-events-none', className)}
162
+ hidden={true}
163
+ placeholder={' '}
164
+ readOnly={true}
165
+ value={value ?? ''}
166
+ />
167
+ </div>
168
+ )
169
+ }
170
+
171
+ export function SelectMultiValue({
172
+ className,
173
+ value,
174
+ placeholder,
175
+ children,
176
+ ...props
177
+ }: ComponentProps<'input'>) {
178
+ const { variant } = useFieldContext()
179
+
180
+ const shouldShowPlaceholder = useMemo(() => {
181
+ if (variant === 'filter') return false
182
+ return Array.isArray(value) && value.length === 0 && placeholder
183
+ }, [value, placeholder, variant])
184
+
185
+ return (
186
+ <div
187
+ className={twMerge(
188
+ className,
189
+ 'gap-small-1x scrollbar-hide flex w-full overflow-x-hidden',
190
+ 'group-disabled:!pl-0'
191
+ )}
192
+ >
193
+ {shouldShowPlaceholder && (
194
+ <Typography className="text-neutral-dark group-has-[div[data-slot=date-picker-left-slot]]:pl-large-1x">
195
+ {placeholder}
196
+ </Typography>
197
+ )}
198
+
199
+ {children}
200
+
201
+ <input
202
+ {...props}
203
+ aria-readonly={true}
204
+ className={twMerge(className, 'pointer-events-none')}
205
+ hidden={true}
206
+ placeholder={' '}
207
+ readOnly={true}
208
+ value={value}
209
+ />
210
+ </div>
211
+ )
212
+ }
213
+
214
+ export function SelectContent({
215
+ className,
216
+ sideOffset = 5,
217
+ side = 'bottom',
218
+ align = 'start',
219
+ children,
220
+ ...props
221
+ }: ComponentProps<typeof RadixPopover.Content>) {
222
+ const { state } = useFieldContext()
223
+
224
+ return (
225
+ <RadixPopover.Portal>
226
+ <RadixPopover.Content
227
+ align={align}
228
+ className={content({ className, state })}
229
+ side={side}
230
+ sideOffset={sideOffset}
231
+ {...props}
232
+ >
233
+ <ListRoot>{children}</ListRoot>
234
+ </RadixPopover.Content>
235
+ </RadixPopover.Portal>
236
+ )
237
+ }
238
+
239
+ export function SelectCaption({ className, ...props }: ComponentProps<'p'>) {
240
+ const { state } = useFieldContext()
241
+ return <p className={caption({ className, state })} {...props} />
242
+ }
243
+
244
+ export function SelectSlot({ className, ...props }: ComponentProps<'span'>) {
245
+ const { state } = useFieldContext()
246
+ return <span className={slotText({ className, state })} {...props} />
247
+ }
248
+
249
+ export function SelectOptions(props: ComponentProps<typeof ListContent>) {
250
+ return <ListContent {...props} />
251
+ }
252
+
253
+ export function SelectOption({
254
+ className,
255
+ ...props
256
+ }: ComponentProps<typeof ListItem>) {
257
+ return (
258
+ <ListItem className={twMerge(className, 'cursor-pointer')} {...props} />
259
+ )
260
+ }
261
+
262
+ export function SelectOptionText(props: ComponentProps<typeof Typography>) {
263
+ return <Typography {...props} />
264
+ }
265
+
266
+ export function SelectHeader(props: ComponentProps<typeof ListHeader>) {
267
+ return <ListHeader {...props} />
268
+ }
269
+
270
+ export function SelectHeaderTitle(
271
+ props: ComponentProps<typeof ListHeaderTitle>
272
+ ) {
273
+ return <ListHeaderTitle {...props} />
274
+ }
@@ -0,0 +1,15 @@
1
+ import { Button } from '../form/button'
2
+ import { Icon } from '../icon'
3
+
4
+ interface CalendarAddEventProps {
5
+ date: Date
6
+ onAddEvent: (date: Date) => void
7
+ }
8
+
9
+ export function CalendarAddEvent({ date, onAddEvent }: CalendarAddEventProps) {
10
+ return (
11
+ <Button size="icon_sm" variant="outlined" onClick={() => onAddEvent(date)}>
12
+ <Icon className="text-icon-neutral-3" name="add" />
13
+ </Button>
14
+ )
15
+ }
@@ -0,0 +1,12 @@
1
+ import { cx } from '@xjur-ui/util'
2
+ import type { ComponentProps } from 'react'
3
+
4
+ export function CalendarBody({ className, ...props }: ComponentProps<'div'>) {
5
+ return (
6
+ <div
7
+ className={cx(className, 'gap-large-2x p-large flex flex-col')}
8
+ data-slot="calendar-body"
9
+ {...props}
10
+ />
11
+ )
12
+ }
@@ -0,0 +1,120 @@
1
+ import { Fragment, useMemo } from 'react'
2
+ import { useDroppable } from '@dnd-kit/core'
3
+ import { cx, tv } from '@xjur-ui/util'
4
+ import { isPast } from 'date-fns'
5
+ import { Typography } from '../typography'
6
+ import { Button } from '../form/button'
7
+ import { Icon } from '../icon'
8
+ import { isToday } from './helpers/calendar'
9
+ import { useFullCalendar } from './calendar-root'
10
+ import type { ICalendarCell } from './types/calendar-cell'
11
+ import type { ICalendarEvent } from './types/calendar-event'
12
+ import { CalendarMoreEventsDropdown } from './calendar-more-events-dropdown'
13
+
14
+ interface CalendarCellProps {
15
+ events: ICalendarEvent[]
16
+ cell: ICalendarCell
17
+ }
18
+
19
+ const calendarCellVariants = tv({
20
+ base: 'group/calendar-cell p-small flex flex-col gap-small-1x w-full bg-layer-2-idle ',
21
+ variants: {
22
+ type: {
23
+ month: 'h-[212px]',
24
+ week: 'min-h-[64px] max-h-[212px]',
25
+ day: 'min-h-[64px] max-h-[212px]'
26
+ }
27
+ }
28
+ })
29
+
30
+ export function CalendarCell({ cell, events }: CalendarCellProps) {
31
+ const { date, type } = cell
32
+
33
+ const { renderEvent, activeEventId, onAddEvent, disableEventCreationInPast } =
34
+ useFullCalendar()
35
+ const eventsToShow = useMemo(() => events.slice(0, 2), [events])
36
+ const hasMore = events.length >= 3
37
+
38
+ const { isOver, setNodeRef } = useDroppable({
39
+ id: `calendar-cell-${type}-${date.toISOString()}`,
40
+ data: {
41
+ date,
42
+ type
43
+ }
44
+ })
45
+
46
+ const isDraggingInCell = useMemo(() => {
47
+ const cellEvent = events.find(event => event.id === activeEventId)
48
+
49
+ if (!cellEvent) return false
50
+
51
+ const formatDate = (date: Date) => {
52
+ return date.toLocaleDateString('pt-BR', {
53
+ year: 'numeric',
54
+ month: '2-digit',
55
+ day: '2-digit'
56
+ })
57
+ }
58
+
59
+ const cellDate = formatDate(date)
60
+ const cellEventDate = formatDate(cellEvent.eventDate)
61
+
62
+ return cellDate === cellEventDate
63
+ }, [activeEventId, date, events])
64
+
65
+ const calendarCellClassNames = calendarCellVariants({ type })
66
+
67
+ const disableEventCreation = useMemo(
68
+ () => disableEventCreationInPast && isPast(date) && !isToday(date),
69
+ [disableEventCreationInPast, date]
70
+ )
71
+
72
+ return (
73
+ <div
74
+ className={calendarCellClassNames}
75
+ data-slot="calendar-cell"
76
+ ref={setNodeRef}
77
+ >
78
+ {type === 'month' && (
79
+ <div className="flex items-center justify-center">
80
+ <div
81
+ className={cx(
82
+ 'size-large-2x rounded-circle bg-layer-2-idle flex items-center justify-center',
83
+ isToday(date) && 'bg-primary-idle text-neutral-label'
84
+ )}
85
+ >
86
+ <Typography size="sm" variant="label" weight="medium">
87
+ {cell.date.getDate()}
88
+ </Typography>
89
+ </div>
90
+ </div>
91
+ )}
92
+
93
+ <div className="gap-small-1x flex flex-col">
94
+ {eventsToShow.map(event => (
95
+ <Fragment key={event.id}>{renderEvent(event)}</Fragment>
96
+ ))}
97
+
98
+ {isOver && eventsToShow.length < 2 && !isDraggingInCell && (
99
+ <div className="border-border-layer-4 rounded-small-2x h-[68px] w-full border border-dashed" />
100
+ )}
101
+ </div>
102
+
103
+ <div className="mt-auto flex items-center justify-between">
104
+ {hasMore && <CalendarMoreEventsDropdown events={events.slice(2)} />}
105
+
106
+ {onAddEvent && !disableEventCreation && (
107
+ <div className="invisible ml-auto transition-opacity duration-100 ease-in-out group-hover/calendar-cell:visible">
108
+ <Button
109
+ size="icon_sm"
110
+ variant="outlined"
111
+ onClick={() => onAddEvent(date)}
112
+ >
113
+ <Icon className="text-icon-neutral-3" name="add" />
114
+ </Button>
115
+ </div>
116
+ )}
117
+ </div>
118
+ </div>
119
+ )
120
+ }
@@ -0,0 +1,76 @@
1
+ import { useCallback } from 'react'
2
+ import { cx } from '@xjur-ui/util'
3
+ import { setHours } from 'date-fns'
4
+ import { Typography } from '../typography'
5
+ import { WEEK_HOURS, getEventsForDayAndHour } from './helpers/calendar'
6
+ import { useFullCalendar } from './calendar-root'
7
+ import { CalendarWeekDay } from './calendar-week-day'
8
+ import { CalendarCell } from './calendar-cell'
9
+ import type { ICalendarCell } from './types/calendar-cell'
10
+
11
+ export function CalendarDayView() {
12
+ const { selectedDate, events } = useFullCalendar()
13
+
14
+ const getEventsForDayAndHourCallback = useCallback(
15
+ (date: Date, hour: number) => {
16
+ return getEventsForDayAndHour(events, date, hour)
17
+ },
18
+ [events]
19
+ )
20
+
21
+ const cellsWithHour = useCallback((cell: ICalendarCell, hour: number) => {
22
+ return {
23
+ ...cell,
24
+ date: setHours(cell.date, hour)
25
+ }
26
+ }, [])
27
+
28
+ return (
29
+ <div className="bg-layer-2-hover rounded-small-1x border-border-layer-2 scrollbar-hide h-full w-full border">
30
+ <div className="flex flex-1 flex-col">
31
+ <div
32
+ className="bg-layer-2-hover sticky top-0 z-10 flex w-full"
33
+ data-slot="week-header"
34
+ >
35
+ <div className="w-[64px]" />
36
+ <CalendarWeekDay
37
+ className="border-border-layer-2 items-start border-l"
38
+ date={selectedDate}
39
+ />
40
+ </div>
41
+
42
+ <div className="overflow-hidden">
43
+ {WEEK_HOURS.map(({ hour, label }) => (
44
+ <div className="flex items-start" key={hour}>
45
+ <div className="px-small flex h-full w-[64px] items-start justify-end">
46
+ <Typography size="sm-1x" variant="label" weight="medium">
47
+ {label}
48
+ </Typography>
49
+ </div>
50
+
51
+ <div
52
+ className={cx(
53
+ 'flex flex-1',
54
+ '[&>*]:border-border-layer-2',
55
+ '[&>*]:border-t',
56
+ '[&>*]:border-l'
57
+ )}
58
+ >
59
+ <CalendarCell
60
+ cell={cellsWithHour(
61
+ {
62
+ date: selectedDate,
63
+ type: 'day'
64
+ },
65
+ hour
66
+ )}
67
+ events={getEventsForDayAndHourCallback(selectedDate, hour)}
68
+ />
69
+ </div>
70
+ </div>
71
+ ))}
72
+ </div>
73
+ </div>
74
+ </div>
75
+ )
76
+ }
@@ -0,0 +1,178 @@
1
+ import { cx, tv } from '@xjur-ui/util'
2
+ import type { ComponentProps } from 'react'
3
+ import { useDraggable } from '@dnd-kit/core'
4
+ import { Typography } from '../typography'
5
+ import { Tooltip, TooltipContent, TooltipTrigger } from '../tooltip'
6
+ import type {
7
+ ICalendarEvent,
8
+ ICalendarEventStatus
9
+ } from './types/calendar-event'
10
+ import { useFullCalendar } from './calendar-root'
11
+
12
+ const eventVariants = tv({
13
+ base: 'py-small_1x-alt pr-small pl-medium rounded-small-2x transition-colors duration-100 ease-out',
14
+ variants: {
15
+ status: {
16
+ pending:
17
+ 'bg-layer-2-hover border-l-2 border-border-layer-4 hover:bg-layer-2-pressed active:bg-layer-2-active',
18
+ completed:
19
+ 'bg-success-alt-idle border-l-2 border-success-idle hover:bg-success-alt-hover active:bg-success-alt-pressed',
20
+ cancelled:
21
+ 'bg-danger-alt-idle border-l-2 border-danger-idle hover:bg-danger-alt-hover active:bg-danger-alt-pressed'
22
+ }
23
+ },
24
+ defaultVariants: {
25
+ status: 'pending'
26
+ }
27
+ })
28
+
29
+ interface CalendarEventProps extends ComponentProps<'div'> {
30
+ event: ICalendarEvent
31
+ disabled?: boolean
32
+ status?: ICalendarEventStatus
33
+ }
34
+
35
+ export function CalendarEvent({
36
+ event,
37
+ disabled = false,
38
+ status = 'pending',
39
+ className,
40
+ children,
41
+ ...props
42
+ }: CalendarEventProps) {
43
+ const { onEventMove } = useFullCalendar()
44
+ const isDraggingDisabled = disabled || !onEventMove
45
+
46
+ const { attributes, listeners, setNodeRef, transform, isDragging } =
47
+ useDraggable({
48
+ id: event.id,
49
+ disabled: isDraggingDisabled,
50
+ data: {
51
+ event,
52
+ type: 'calendar-event'
53
+ }
54
+ })
55
+
56
+ const style = transform
57
+ ? {
58
+ transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`
59
+ }
60
+ : undefined
61
+
62
+ return (
63
+ <div
64
+ className={cx(
65
+ disabled && 'pointer-events-none',
66
+ 'cursor-pointer active:cursor-grabbing',
67
+ isDragging && 'z-1000 -rotate-2',
68
+ eventVariants({ status }),
69
+ className
70
+ )}
71
+ data-draggable-event-id={event.id}
72
+ data-slot="calendar-event"
73
+ ref={setNodeRef}
74
+ style={style}
75
+ {...listeners}
76
+ {...attributes}
77
+ {...props}
78
+ >
79
+ {children}
80
+ </div>
81
+ )
82
+ }
83
+
84
+ export function CalendarEventTitle({
85
+ size = 'sm',
86
+ variant = 'label',
87
+ weight = 'medium',
88
+ className,
89
+ ...props
90
+ }: ComponentProps<typeof Typography>) {
91
+ const { activeEventId } = useFullCalendar()
92
+
93
+ if (activeEventId !== null) {
94
+ return (
95
+ <Typography
96
+ className={cx(className, 'text-title-neutral truncate')}
97
+ size={size}
98
+ variant={variant}
99
+ weight={weight}
100
+ {...props}
101
+ />
102
+ )
103
+ }
104
+
105
+ return (
106
+ <Tooltip delayDuration={500}>
107
+ <TooltipTrigger asChild={true}>
108
+ <Typography
109
+ className={cx(className, 'text-title-neutral truncate')}
110
+ size={size}
111
+ variant={variant}
112
+ weight={weight}
113
+ {...props}
114
+ />
115
+ </TooltipTrigger>
116
+ <TooltipContent className="max-w-[320px]">
117
+ {props.children}
118
+ </TooltipContent>
119
+ </Tooltip>
120
+ )
121
+ }
122
+
123
+ export function CalendarEventDescription({
124
+ size = 'sm-1x',
125
+ variant = 'body',
126
+ weight = 'normal',
127
+ className,
128
+ ...props
129
+ }: ComponentProps<typeof Typography>) {
130
+ const { activeEventId } = useFullCalendar()
131
+
132
+ if (activeEventId !== null) {
133
+ return (
134
+ <Typography
135
+ className={cx(className, 'truncate')}
136
+ size={size}
137
+ variant={variant}
138
+ weight={weight}
139
+ {...props}
140
+ />
141
+ )
142
+ }
143
+
144
+ return (
145
+ <Tooltip delayDuration={500}>
146
+ <TooltipTrigger asChild={true}>
147
+ <Typography
148
+ className={cx(className, 'truncate')}
149
+ size={size}
150
+ variant={variant}
151
+ weight={weight}
152
+ {...props}
153
+ />
154
+ </TooltipTrigger>
155
+ <TooltipContent className="max-w-[320px]">
156
+ {props.children}
157
+ </TooltipContent>
158
+ </Tooltip>
159
+ )
160
+ }
161
+
162
+ export function CalendarEventStatus({
163
+ variant = 'body',
164
+ size = 'sm-1x',
165
+ weight = 'normal',
166
+ className,
167
+ ...props
168
+ }: ComponentProps<typeof Typography>) {
169
+ return (
170
+ <Typography
171
+ className={cx(className, 'truncate')}
172
+ size={size}
173
+ variant={variant}
174
+ weight={weight}
175
+ {...props}
176
+ />
177
+ )
178
+ }
@@ -0,0 +1,14 @@
1
+ import { cx } from '@xjur-ui/util'
2
+ import type { ComponentProps } from 'react'
3
+
4
+ export function CalendarHeader({ className, ...props }: ComponentProps<'div'>) {
5
+ return (
6
+ <div
7
+ {...props}
8
+ className={cx(
9
+ className,
10
+ 'gap-medium h-large-4x flex w-full items-center'
11
+ )}
12
+ />
13
+ )
14
+ }