@xjur-ui/react 2.0.0 → 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 (284) hide show
  1. package/.turbo/turbo-build.log +278 -119
  2. package/CHANGELOG.md +70 -0
  3. package/dist/chunk-2CM3SFOY.js +2 -0
  4. package/dist/chunk-2CM3SFOY.js.map +1 -0
  5. package/dist/chunk-2CTBH6VI.js +2 -0
  6. package/dist/chunk-2CTBH6VI.js.map +1 -0
  7. package/dist/chunk-4BGTC333.js +2 -0
  8. package/dist/chunk-4BGTC333.js.map +1 -0
  9. package/dist/chunk-5WLIDYZH.js +2 -0
  10. package/dist/chunk-5WLIDYZH.js.map +1 -0
  11. package/dist/chunk-6AD6O6II.js +2 -0
  12. package/dist/chunk-6AD6O6II.js.map +1 -0
  13. package/dist/chunk-AA6V5YEC.js +2 -0
  14. package/dist/chunk-AA6V5YEC.js.map +1 -0
  15. package/dist/chunk-BK6FP63A.js +2 -0
  16. package/dist/chunk-BK6FP63A.js.map +1 -0
  17. package/dist/chunk-BZDGWC5O.js +2 -0
  18. package/dist/chunk-BZDGWC5O.js.map +1 -0
  19. package/dist/chunk-CI3ZXWEX.js +2 -0
  20. package/dist/chunk-CI3ZXWEX.js.map +1 -0
  21. package/dist/chunk-DFXHNK5D.js +2 -0
  22. package/dist/chunk-DFXHNK5D.js.map +1 -0
  23. package/dist/chunk-EXC2XOL6.js +2 -0
  24. package/dist/chunk-EXC2XOL6.js.map +1 -0
  25. package/dist/chunk-F4DYKYWJ.js +2 -0
  26. package/dist/chunk-F4DYKYWJ.js.map +1 -0
  27. package/dist/chunk-F5ZLEQGN.js +2 -0
  28. package/dist/chunk-F5ZLEQGN.js.map +1 -0
  29. package/dist/chunk-IKL6PSXU.js +2 -0
  30. package/dist/chunk-IKL6PSXU.js.map +1 -0
  31. package/dist/chunk-IRHU7PDO.js +2 -0
  32. package/dist/chunk-IRHU7PDO.js.map +1 -0
  33. package/dist/chunk-J4X5RQTR.js +2 -0
  34. package/dist/chunk-J4X5RQTR.js.map +1 -0
  35. package/dist/chunk-L4ET6GIZ.js +2 -0
  36. package/dist/chunk-L4ET6GIZ.js.map +1 -0
  37. package/dist/chunk-MZSV4LNY.js +2 -0
  38. package/dist/chunk-MZSV4LNY.js.map +1 -0
  39. package/dist/chunk-OS53BV63.js +3 -0
  40. package/dist/chunk-OS53BV63.js.map +1 -0
  41. package/dist/{chunk-FASEHVMD.js → chunk-PKCW37CJ.js} +2 -2
  42. package/dist/chunk-PKCW37CJ.js.map +1 -0
  43. package/dist/chunk-SLAAEXWI.js +2 -0
  44. package/dist/chunk-SLAAEXWI.js.map +1 -0
  45. package/dist/chunk-SXGSWVMZ.js +2 -0
  46. package/dist/chunk-SXGSWVMZ.js.map +1 -0
  47. package/dist/chunk-TSVURBUY.js +2 -0
  48. package/dist/chunk-TSVURBUY.js.map +1 -0
  49. package/dist/chunk-UXIVZWLB.js +2 -0
  50. package/dist/chunk-UXIVZWLB.js.map +1 -0
  51. package/dist/chunk-WEBAXQID.js +2 -0
  52. package/dist/chunk-WEBAXQID.js.map +1 -0
  53. package/dist/chunk-WV7QV2PU.js +2 -0
  54. package/dist/chunk-WV7QV2PU.js.map +1 -0
  55. package/dist/{components/switch.js → chunk-Z47R2CIM.js} +2 -2
  56. package/dist/chunk-Z47R2CIM.js.map +1 -0
  57. package/dist/chunk-ZVVPUP7V.js +2 -0
  58. package/dist/chunk-ZVVPUP7V.js.map +1 -0
  59. package/dist/components/breadcrumb.d.ts +20 -0
  60. package/dist/components/breadcrumb.js +2 -0
  61. package/dist/components/breadcrumb.js.map +1 -0
  62. package/dist/components/chip.d.ts +2 -1
  63. package/dist/components/chip.js +1 -1
  64. package/dist/components/dialog.d.ts +51 -0
  65. package/dist/components/dialog.js +2 -0
  66. package/dist/components/dialog.js.map +1 -0
  67. package/dist/components/drag-and-drop/drag-handle.d.ts +15 -0
  68. package/dist/components/drag-and-drop/drag-handle.js +2 -0
  69. package/dist/components/drag-and-drop/drag-handle.js.map +1 -0
  70. package/dist/components/drag-and-drop/drag-list-item.d.ts +14 -0
  71. package/dist/components/drag-and-drop/drag-list-item.js +2 -0
  72. package/dist/components/drag-and-drop/drag-list-item.js.map +1 -0
  73. package/dist/components/drag-and-drop/drag-list.d.ts +14 -0
  74. package/dist/components/drag-and-drop/drag-list.js +2 -0
  75. package/dist/components/drag-and-drop/drag-list.js.map +1 -0
  76. package/dist/components/drag-and-drop/drag-root.d.ts +6 -0
  77. package/dist/components/drag-and-drop/drag-root.js +2 -0
  78. package/dist/components/drag-and-drop/drag-root.js.map +1 -0
  79. package/dist/components/drag-and-drop/index.d.ts +10 -0
  80. package/dist/components/drag-and-drop/index.js +2 -0
  81. package/dist/components/drag-and-drop/index.js.map +1 -0
  82. package/dist/components/drag-and-drop/types/drag-item.d.ts +9 -0
  83. package/dist/components/drag-and-drop/types/drag-item.js +2 -0
  84. package/dist/components/drag-and-drop/types/drag-item.js.map +1 -0
  85. package/dist/components/form/button.js +2 -0
  86. package/dist/components/form/calendar.js +2 -0
  87. package/dist/components/form/calendar.js.map +1 -0
  88. package/dist/components/form/checkbox.js +2 -0
  89. package/dist/components/form/checkbox.js.map +1 -0
  90. package/dist/components/form/context/field.context.d.ts +15 -0
  91. package/dist/components/form/context/field.context.js +2 -0
  92. package/dist/components/form/context/field.context.js.map +1 -0
  93. package/dist/components/form/date-picker.d.ts +84 -0
  94. package/dist/components/form/date-picker.js +2 -0
  95. package/dist/components/form/date-picker.js.map +1 -0
  96. package/dist/components/form/floating-label.d.ts +6 -0
  97. package/dist/components/form/floating-label.js +2 -0
  98. package/dist/components/form/floating-label.js.map +1 -0
  99. package/dist/components/form/input.d.ts +95 -0
  100. package/dist/components/form/input.js +2 -0
  101. package/dist/components/form/input.js.map +1 -0
  102. package/dist/components/form/otp-input.js.map +1 -0
  103. package/dist/components/form/radio.js +2 -0
  104. package/dist/components/form/radio.js.map +1 -0
  105. package/dist/components/form/rich-editor.js +2 -0
  106. package/dist/components/form/rich-editor.js.map +1 -0
  107. package/dist/components/form/search-input.js +2 -0
  108. package/dist/components/form/search-input.js.map +1 -0
  109. package/dist/components/form/select.d.ts +94 -0
  110. package/dist/components/form/select.js +2 -0
  111. package/dist/components/form/select.js.map +1 -0
  112. package/dist/components/form/switch.js +2 -0
  113. package/dist/components/form/switch.js.map +1 -0
  114. package/dist/components/full-calendar/calendar-add-event.d.ts +9 -0
  115. package/dist/components/full-calendar/calendar-add-event.js +2 -0
  116. package/dist/components/full-calendar/calendar-add-event.js.map +1 -0
  117. package/dist/components/full-calendar/calendar-body.d.ts +6 -0
  118. package/dist/components/full-calendar/calendar-body.js +2 -0
  119. package/dist/components/full-calendar/calendar-body.js.map +1 -0
  120. package/dist/components/full-calendar/calendar-cell.d.ts +11 -0
  121. package/dist/components/full-calendar/calendar-cell.js +2 -0
  122. package/dist/components/full-calendar/calendar-cell.js.map +1 -0
  123. package/dist/components/full-calendar/calendar-day-view.d.ts +5 -0
  124. package/dist/components/full-calendar/calendar-day-view.js +2 -0
  125. package/dist/components/full-calendar/calendar-day-view.js.map +1 -0
  126. package/dist/components/full-calendar/calendar-event.d.ts +18 -0
  127. package/dist/components/full-calendar/calendar-event.js +2 -0
  128. package/dist/components/full-calendar/calendar-event.js.map +1 -0
  129. package/dist/components/full-calendar/calendar-header.d.ts +6 -0
  130. package/dist/components/full-calendar/calendar-header.js +2 -0
  131. package/dist/components/full-calendar/calendar-header.js.map +1 -0
  132. package/dist/components/full-calendar/calendar-month-view.d.ts +5 -0
  133. package/dist/components/full-calendar/calendar-month-view.js +2 -0
  134. package/dist/components/full-calendar/calendar-month-view.js.map +1 -0
  135. package/dist/components/full-calendar/calendar-more-events-dropdown.d.ts +9 -0
  136. package/dist/components/full-calendar/calendar-more-events-dropdown.js +2 -0
  137. package/dist/components/full-calendar/calendar-more-events-dropdown.js.map +1 -0
  138. package/dist/components/full-calendar/calendar-navigator.d.ts +5 -0
  139. package/dist/components/full-calendar/calendar-navigator.js +2 -0
  140. package/dist/components/full-calendar/calendar-navigator.js.map +1 -0
  141. package/dist/components/full-calendar/calendar-root.d.ts +30 -0
  142. package/dist/components/full-calendar/calendar-root.js +2 -0
  143. package/dist/components/full-calendar/calendar-root.js.map +1 -0
  144. package/dist/components/full-calendar/calendar-today-button.d.ts +9 -0
  145. package/dist/components/full-calendar/calendar-today-button.js +2 -0
  146. package/dist/components/full-calendar/calendar-today-button.js.map +1 -0
  147. package/dist/components/full-calendar/calendar-toggle-view.d.ts +5 -0
  148. package/dist/components/full-calendar/calendar-toggle-view.js +2 -0
  149. package/dist/components/full-calendar/calendar-toggle-view.js.map +1 -0
  150. package/dist/components/full-calendar/calendar-view-renderer.d.ts +5 -0
  151. package/dist/components/full-calendar/calendar-view-renderer.js +2 -0
  152. package/dist/components/full-calendar/calendar-view-renderer.js.map +1 -0
  153. package/dist/components/full-calendar/calendar-week-day.d.ts +10 -0
  154. package/dist/components/full-calendar/calendar-week-day.js +2 -0
  155. package/dist/components/full-calendar/calendar-week-day.js.map +1 -0
  156. package/dist/components/full-calendar/calendar-week-view.d.ts +5 -0
  157. package/dist/components/full-calendar/calendar-week-view.js +2 -0
  158. package/dist/components/full-calendar/calendar-week-view.js.map +1 -0
  159. package/dist/components/full-calendar/helpers/calendar.d.ts +25 -0
  160. package/dist/components/full-calendar/helpers/calendar.js +2 -0
  161. package/dist/components/full-calendar/helpers/calendar.js.map +1 -0
  162. package/dist/components/full-calendar/index.d.ts +18 -0
  163. package/dist/components/full-calendar/index.js +2 -0
  164. package/dist/components/full-calendar/index.js.map +1 -0
  165. package/dist/components/full-calendar/types/calendar-cell.d.ts +6 -0
  166. package/dist/components/full-calendar/types/calendar-cell.js +2 -0
  167. package/dist/components/full-calendar/types/calendar-cell.js.map +1 -0
  168. package/dist/components/full-calendar/types/calendar-event.d.ts +8 -0
  169. package/dist/components/full-calendar/types/calendar-event.js +2 -0
  170. package/dist/components/full-calendar/types/calendar-event.js.map +1 -0
  171. package/dist/components/full-calendar/types/calendar-view.d.ts +3 -0
  172. package/dist/components/full-calendar/types/calendar-view.js +2 -0
  173. package/dist/components/full-calendar/types/calendar-view.js.map +1 -0
  174. package/dist/components/full-calendar/types/calendar-week-hour.d.ts +6 -0
  175. package/dist/components/full-calendar/types/calendar-week-hour.js +2 -0
  176. package/dist/components/full-calendar/types/calendar-week-hour.js.map +1 -0
  177. package/dist/components/horizontal-scroll.d.ts +11 -0
  178. package/dist/components/horizontal-scroll.js +2 -0
  179. package/dist/components/horizontal-scroll.js.map +1 -0
  180. package/dist/components/icon.d.ts +3 -4
  181. package/dist/components/icon.js +1 -1
  182. package/dist/components/selection-bar.d.ts +57 -0
  183. package/dist/components/selection-bar.js +2 -0
  184. package/dist/components/selection-bar.js.map +1 -0
  185. package/dist/components/sheet.d.ts +8 -8
  186. package/dist/components/sheet.js +1 -1
  187. package/dist/components/sheet.js.map +1 -1
  188. package/dist/components/table.js +1 -1
  189. package/dist/components/tag.d.ts +2 -1
  190. package/dist/components/tag.js +1 -1
  191. package/dist/components/upload.d.ts +74 -0
  192. package/dist/components/upload.js +2 -0
  193. package/dist/components/upload.js.map +1 -0
  194. package/dist/icons-CmDuL0gZ.d.ts +4 -0
  195. package/dist/index.css +1 -1
  196. package/dist/index.css.map +1 -1
  197. package/package.json +22 -13
  198. package/src/components/breadcrumb.tsx +119 -0
  199. package/src/components/dialog.tsx +242 -0
  200. package/src/components/drag-and-drop/drag-handle.tsx +46 -0
  201. package/src/components/drag-and-drop/drag-list-item.tsx +91 -0
  202. package/src/components/drag-and-drop/drag-list.tsx +47 -0
  203. package/src/components/drag-and-drop/drag-root.tsx +30 -0
  204. package/src/components/drag-and-drop/index.ts +39 -0
  205. package/src/components/drag-and-drop/types/drag-item.ts +7 -0
  206. package/src/components/{calendar.tsx → form/calendar.tsx} +2 -2
  207. package/src/components/{checkbox.tsx → form/checkbox.tsx} +2 -2
  208. package/src/components/form/context/field.context.ts +27 -0
  209. package/src/components/form/date-picker.tsx +199 -0
  210. package/src/components/form/floating-label.tsx +60 -0
  211. package/src/components/form/input.tsx +235 -0
  212. package/src/components/{radio.tsx → form/radio.tsx} +1 -1
  213. package/src/components/{rich-editor.tsx → form/rich-editor.tsx} +6 -6
  214. package/src/components/{search-input.tsx → form/search-input.tsx} +2 -2
  215. package/src/components/form/select.tsx +274 -0
  216. package/src/components/full-calendar/calendar-add-event.tsx +15 -0
  217. package/src/components/full-calendar/calendar-body.tsx +12 -0
  218. package/src/components/full-calendar/calendar-cell.tsx +120 -0
  219. package/src/components/full-calendar/calendar-day-view.tsx +76 -0
  220. package/src/components/full-calendar/calendar-event.tsx +178 -0
  221. package/src/components/full-calendar/calendar-header.tsx +14 -0
  222. package/src/components/full-calendar/calendar-month-view.tsx +69 -0
  223. package/src/components/full-calendar/calendar-more-events-dropdown.tsx +39 -0
  224. package/src/components/full-calendar/calendar-navigator.tsx +86 -0
  225. package/src/components/full-calendar/calendar-root.tsx +165 -0
  226. package/src/components/full-calendar/calendar-today-button.tsx +21 -0
  227. package/src/components/full-calendar/calendar-toggle-view.tsx +61 -0
  228. package/src/components/full-calendar/calendar-view-renderer.tsx +19 -0
  229. package/src/components/full-calendar/calendar-week-day.tsx +49 -0
  230. package/src/components/full-calendar/calendar-week-view.tsx +88 -0
  231. package/src/components/full-calendar/helpers/calendar.ts +158 -0
  232. package/src/components/full-calendar/index.ts +16 -0
  233. package/src/components/full-calendar/types/calendar-cell.ts +4 -0
  234. package/src/components/full-calendar/types/calendar-event.ts +7 -0
  235. package/src/components/full-calendar/types/calendar-view.ts +1 -0
  236. package/src/components/full-calendar/types/calendar-week-hour.ts +4 -0
  237. package/src/components/horizontal-scroll.tsx +159 -0
  238. package/src/components/selection-bar.tsx +273 -0
  239. package/src/components/sheet.tsx +2 -2
  240. package/src/components/upload.tsx +647 -0
  241. package/src/resources/icons.ts +4 -1
  242. package/dist/chunk-FASEHVMD.js.map +0 -1
  243. package/dist/chunk-NPTLORW5.js +0 -2
  244. package/dist/chunk-NPTLORW5.js.map +0 -1
  245. package/dist/chunk-SHHXKVVR.js +0 -2
  246. package/dist/chunk-SHHXKVVR.js.map +0 -1
  247. package/dist/components/button.js +0 -2
  248. package/dist/components/calendar.js +0 -2
  249. package/dist/components/calendar.js.map +0 -1
  250. package/dist/components/checkbox.js +0 -2
  251. package/dist/components/checkbox.js.map +0 -1
  252. package/dist/components/date-picker.d.ts +0 -25
  253. package/dist/components/date-picker.js +0 -2
  254. package/dist/components/date-picker.js.map +0 -1
  255. package/dist/components/input.d.ts +0 -37
  256. package/dist/components/input.js +0 -2
  257. package/dist/components/input.js.map +0 -1
  258. package/dist/components/otp-input.js.map +0 -1
  259. package/dist/components/radio.js +0 -2
  260. package/dist/components/radio.js.map +0 -1
  261. package/dist/components/rich-editor.js +0 -2
  262. package/dist/components/rich-editor.js.map +0 -1
  263. package/dist/components/search-input.js +0 -2
  264. package/dist/components/search-input.js.map +0 -1
  265. package/dist/components/select.d.ts +0 -36
  266. package/dist/components/select.js +0 -2
  267. package/dist/components/select.js.map +0 -1
  268. package/dist/components/switch.js.map +0 -1
  269. package/src/components/date-picker.tsx +0 -263
  270. package/src/components/input.tsx +0 -320
  271. package/src/components/select.tsx +0 -318
  272. /package/dist/components/{button.d.ts → form/button.d.ts} +0 -0
  273. /package/dist/components/{button.js.map → form/button.js.map} +0 -0
  274. /package/dist/components/{calendar.d.ts → form/calendar.d.ts} +0 -0
  275. /package/dist/components/{checkbox.d.ts → form/checkbox.d.ts} +0 -0
  276. /package/dist/components/{otp-input.d.ts → form/otp-input.d.ts} +0 -0
  277. /package/dist/components/{otp-input.js → form/otp-input.js} +0 -0
  278. /package/dist/components/{radio.d.ts → form/radio.d.ts} +0 -0
  279. /package/dist/components/{rich-editor.d.ts → form/rich-editor.d.ts} +0 -0
  280. /package/dist/components/{search-input.d.ts → form/search-input.d.ts} +0 -0
  281. /package/dist/components/{switch.d.ts → form/switch.d.ts} +0 -0
  282. /package/src/components/{button.tsx → form/button.tsx} +0 -0
  283. /package/src/components/{otp-input.tsx → form/otp-input.tsx} +0 -0
  284. /package/src/components/{switch.tsx → form/switch.tsx} +0 -0
@@ -0,0 +1,158 @@
1
+ import {
2
+ endOfMonth,
3
+ startOfMonth,
4
+ subMonths,
5
+ isToday as isTodayDateFns,
6
+ isSameDay,
7
+ endOfWeek,
8
+ startOfWeek,
9
+ eachDayOfInterval
10
+ } from 'date-fns'
11
+ import type { ICalendarEvent } from '../types/calendar-event'
12
+ import type { ICalendarCell } from '../types/calendar-cell'
13
+ import type { ICalendarWeekHour } from '../types/calendar-week-hour'
14
+
15
+ function arrayFromLength(length: number) {
16
+ return Array.from({ length }, (_, i) => i)
17
+ }
18
+
19
+ export const WEEKDAYS = [
20
+ 'Domingo',
21
+ 'Segunda',
22
+ 'Terça',
23
+ 'Quarta',
24
+ 'Quinta',
25
+ 'Sexta',
26
+ 'Sábado'
27
+ ]
28
+
29
+ export const WEEK_HOURS: ICalendarWeekHour[] = Array.from(
30
+ { length: 16 },
31
+ (_, i) => {
32
+ const hour = i + 8
33
+ return {
34
+ hour,
35
+ label: `${hour.toString().padStart(2, '0')}:00`
36
+ }
37
+ }
38
+ )
39
+
40
+ export function getDaysInMonth(date: Date): ICalendarCell[] {
41
+ const year = date.getFullYear()
42
+ const month = date.getMonth()
43
+
44
+ const firstWeekdayOfMonth = startOfMonth(date).getDay()
45
+ const daysInPrevMonth = endOfMonth(subMonths(date, 1)).getDate()
46
+ const daysInMonth = endOfMonth(date).getDate()
47
+
48
+ const prevMonthDays = arrayFromLength(firstWeekdayOfMonth).map<ICalendarCell>(
49
+ dayIndex => {
50
+ dayIndex += 1
51
+ const prevMonth = month - 1
52
+ const dayOfPrevMonth = daysInPrevMonth - firstWeekdayOfMonth
53
+ const day = dayOfPrevMonth + dayIndex
54
+ const date = new Date(year, prevMonth, day)
55
+
56
+ return {
57
+ dayOfWeekNumber: date.getDay(),
58
+ date,
59
+ type: 'month'
60
+ }
61
+ }
62
+ )
63
+
64
+ const currentMonthDays = arrayFromLength(daysInMonth).map<ICalendarCell>(
65
+ dayIndex => {
66
+ const day = dayIndex + 1
67
+ const date = new Date(year, month, day)
68
+ return {
69
+ dayOfWeekNumber: date.getDay(),
70
+ date,
71
+ type: 'month'
72
+ }
73
+ }
74
+ )
75
+
76
+ const totalWeekdays = 7
77
+ const totalDays = firstWeekdayOfMonth + daysInMonth
78
+ const remainingDays =
79
+ totalWeekdays - ((totalDays % totalWeekdays) % totalWeekdays)
80
+
81
+ const nextMonthDays = arrayFromLength(remainingDays).map<ICalendarCell>(
82
+ dayIndex => {
83
+ const day = dayIndex + 1
84
+ const date = new Date(year, month + 1, day)
85
+ return {
86
+ dayOfWeekNumber: date.getDay(),
87
+ date,
88
+ type: 'month'
89
+ }
90
+ }
91
+ )
92
+
93
+ return [...prevMonthDays, ...currentMonthDays, ...nextMonthDays]
94
+ }
95
+
96
+ export function getEventsForDay(events: ICalendarEvent[], date: Date) {
97
+ return events.filter(event => isSameDay(event.eventDate, date))
98
+ }
99
+
100
+ export function isToday(date: Date) {
101
+ return isTodayDateFns(date)
102
+ }
103
+
104
+ /**
105
+ * Week view helpers
106
+ */
107
+
108
+ export function getWeekDaysInMonth(date: Date): ICalendarCell[] {
109
+ const weekStart = startOfWeek(date, { weekStartsOn: 0 }) // Domingo = 0
110
+ const weekEnd = endOfWeek(date, { weekStartsOn: 0 })
111
+ const weekDays = eachDayOfInterval({ start: weekStart, end: weekEnd })
112
+
113
+ const dayOfWeekNumber = weekStart.getDay()
114
+ const dayOfWeekName = WEEKDAYS[dayOfWeekNumber]
115
+
116
+ return weekDays.map(day => ({
117
+ date: day,
118
+ dayOfWeekNumber,
119
+ dayOfWeekName,
120
+ fullDate: day,
121
+ type: 'week'
122
+ }))
123
+ }
124
+
125
+ export function getEventsForDayAndHour(
126
+ events: ICalendarEvent[],
127
+ date: Date,
128
+ hour: number
129
+ ): ICalendarEvent[] {
130
+ return events.filter(event => {
131
+ return (
132
+ isSameDay(event.eventDate, date) && event.eventDate.getHours() === hour
133
+ )
134
+ })
135
+ }
136
+
137
+ export function isCurrentHour(date: Date, hour: number): boolean {
138
+ const now = new Date()
139
+ return isSameDay(now, date) && now.getHours() === hour
140
+ }
141
+
142
+ export function getStartAndEndDateOfWeek(date: Date): {
143
+ start: Date
144
+ end: Date
145
+ } {
146
+ const start = startOfWeek(date, { weekStartsOn: 0 })
147
+ const end = endOfWeek(date, { weekStartsOn: 0 })
148
+ return { start, end }
149
+ }
150
+
151
+ /**
152
+ * Day view helpers
153
+ */
154
+
155
+ export function getDaysInDay(date: Date): ICalendarCell[] {
156
+ const days = eachDayOfInterval({ start: date, end: date })
157
+ return days.map(day => ({ date: day, type: 'day' }))
158
+ }
@@ -0,0 +1,16 @@
1
+ export * from './calendar-month-view'
2
+ export * from './calendar-week-view'
3
+ export * from './calendar-view-renderer'
4
+ export * from './calendar-navigator'
5
+ export * from './calendar-root'
6
+ export * from './calendar-toggle-view'
7
+ export * from './calendar-header'
8
+ export * from './calendar-body'
9
+ export * from './calendar-event'
10
+ export * from './calendar-today-button'
11
+
12
+ export type {
13
+ ICalendarEvent,
14
+ ICalendarEventStatus
15
+ } from './types/calendar-event'
16
+ export type { CalendarView } from './types/calendar-view'
@@ -0,0 +1,4 @@
1
+ export interface ICalendarCell {
2
+ type: 'month' | 'week' | 'day'
3
+ date: Date
4
+ }
@@ -0,0 +1,7 @@
1
+ export interface ICalendarEvent<T = unknown> {
2
+ id: string
3
+ eventDate: Date
4
+ data: T
5
+ }
6
+
7
+ export type ICalendarEventStatus = 'pending' | 'completed' | 'cancelled'
@@ -0,0 +1 @@
1
+ export type CalendarView = 'month' | 'week' | 'day'
@@ -0,0 +1,4 @@
1
+ export interface ICalendarWeekHour {
2
+ hour: number
3
+ label: string
4
+ }
@@ -0,0 +1,159 @@
1
+ import type { ComponentProps, ReactNode } from 'react'
2
+ import { useCallback, useEffect, useRef, useState } from 'react'
3
+ import { cx } from '@xjur-ui/util'
4
+ import { Button } from './form/button'
5
+ import { Icon } from './icon'
6
+
7
+ export interface HorizontalScrollProps extends ComponentProps<'div'> {
8
+ children: ReactNode
9
+ gap?: 'small' | 'medium' | 'large'
10
+ scrollAmount?: number
11
+ }
12
+
13
+ export function HorizontalScroll({
14
+ children,
15
+ className,
16
+ gap = 'small',
17
+ scrollAmount = 200,
18
+ ...props
19
+ }: HorizontalScrollProps) {
20
+ const scrollContainerRef = useRef<HTMLDivElement>(null)
21
+ const [canScrollLeft, setCanScrollLeft] = useState(false)
22
+ const [canScrollRight, setCanScrollRight] = useState(false)
23
+ const [isScrolling, setIsScrolling] = useState(false)
24
+
25
+ const checkScrollable = useCallback(() => {
26
+ const container = scrollContainerRef.current
27
+ if (!container) return
28
+
29
+ const { scrollLeft, scrollWidth, clientWidth } = container
30
+ setCanScrollLeft(scrollLeft > 0)
31
+ setCanScrollRight(scrollLeft < scrollWidth - clientWidth - 1)
32
+ }, [])
33
+
34
+ const handleScrollLeft = useCallback(() => {
35
+ const container = scrollContainerRef.current
36
+ if (!container) return
37
+
38
+ setIsScrolling(true)
39
+ container.scrollTo({
40
+ left: container.scrollLeft - scrollAmount,
41
+ behavior: 'smooth'
42
+ })
43
+
44
+ setTimeout(() => setIsScrolling(false), 300)
45
+ }, [scrollAmount])
46
+
47
+ const handleScrollRight = useCallback(() => {
48
+ const container = scrollContainerRef.current
49
+ if (!container) return
50
+
51
+ setIsScrolling(true)
52
+ container.scrollTo({
53
+ left: container.scrollLeft + scrollAmount,
54
+ behavior: 'smooth'
55
+ })
56
+
57
+ setTimeout(() => setIsScrolling(false), 300)
58
+ }, [scrollAmount])
59
+
60
+ useEffect(() => {
61
+ const container = scrollContainerRef.current
62
+ if (!container) return
63
+
64
+ const handleScroll = () => {
65
+ checkScrollable()
66
+ }
67
+
68
+ const handleResize = () => {
69
+ checkScrollable()
70
+ }
71
+
72
+ checkScrollable()
73
+ container.addEventListener('scroll', handleScroll, { passive: true })
74
+ window.addEventListener('resize', handleResize)
75
+
76
+ let resizeObserver: ResizeObserver | null = null
77
+ if (typeof ResizeObserver !== 'undefined') {
78
+ resizeObserver = new ResizeObserver(() => {
79
+ checkScrollable()
80
+ })
81
+ resizeObserver.observe(container)
82
+ }
83
+
84
+ return () => {
85
+ container.removeEventListener('scroll', handleScroll)
86
+ window.removeEventListener('resize', handleResize)
87
+ if (resizeObserver) {
88
+ resizeObserver.disconnect()
89
+ }
90
+ }
91
+ }, [checkScrollable])
92
+
93
+ const gapClass = {
94
+ small: 'gap-small',
95
+ medium: 'gap-medium',
96
+ large: 'gap-large'
97
+ }[gap]
98
+
99
+ return (
100
+ <div className={cx('relative isolate', className)} {...props}>
101
+ {/* Left Arrow */}
102
+ {canScrollLeft && (
103
+ <div
104
+ className="absolute top-1/2 left-0 z-[3] flex h-full w-[80px] -translate-y-1/2 items-center"
105
+ style={{
106
+ background: `linear-gradient(to right, white 40%, transparent)`
107
+ }}
108
+ >
109
+ <Button
110
+ appearance="ghost"
111
+ aria-label="Scroll left"
112
+ className="ml-0"
113
+ disabled={isScrolling}
114
+ size="icon_md"
115
+ variant="secondary"
116
+ onClick={handleScrollLeft}
117
+ >
118
+ <Icon name="chevron_left" />
119
+ </Button>
120
+ </div>
121
+ )}
122
+
123
+ {/* Right Arrow */}
124
+ {canScrollRight && (
125
+ <div
126
+ className="absolute top-1/2 right-0 z-[2] flex h-full w-[80px] -translate-y-1/2 items-center justify-end"
127
+ style={{
128
+ background: `linear-gradient(to left, white 40%, transparent)`
129
+ }}
130
+ >
131
+ <Button
132
+ appearance="ghost"
133
+ aria-label="Scroll right"
134
+ className="mr-0"
135
+ disabled={isScrolling}
136
+ size="icon_md"
137
+ variant="secondary"
138
+ onClick={handleScrollRight}
139
+ >
140
+ <Icon name="chevron_right" />
141
+ </Button>
142
+ </div>
143
+ )}
144
+
145
+ {/* Scrollable Content */}
146
+ <div
147
+ className={cx(
148
+ 'scrollbar-hide relative z-1 flex overflow-x-auto overflow-y-visible',
149
+ 'min-w-0 [&>*]:flex-none [&>*]:whitespace-nowrap',
150
+ gapClass,
151
+ className
152
+ )}
153
+ ref={scrollContainerRef}
154
+ >
155
+ {children}
156
+ </div>
157
+ </div>
158
+ )
159
+ }
@@ -0,0 +1,273 @@
1
+ import type { ComponentProps, ReactNode } from 'react'
2
+ import { createContext, useContext, useState, useCallback } from 'react'
3
+ import { cva, cx, type ClassVariantProps } from '@xjur-ui/util'
4
+ import { Icon, type IconType } from './icon'
5
+ import { Button } from './form/button'
6
+
7
+ const selectionBarVariants = cva(
8
+ [
9
+ 'flex items-center gap-4 rounded-lg px-4 py-3 shadow-lg transition-colors duration-200 ease-in-out',
10
+ 'fixed bottom-6 left-1/2 -translate-x-1/2 transform z-50',
11
+ 'backdrop-blur-sm bg-white/95 border border-border-layer-2'
12
+ ],
13
+ {
14
+ variants: {
15
+ size: {
16
+ sm: 'px-3 py-2 text-sm',
17
+ md: 'px-4 py-3 text-base',
18
+ lg: 'px-6 py-4 text-lg'
19
+ },
20
+ variant: {
21
+ primary:
22
+ 'bg-primary-idle text-neutral-label hover:bg-primary-hover rounded-circle active:bg-primary-pressed',
23
+ secondary:
24
+ 'bg-secondary-idle text-white border-secondary-idle hover:bg-secondary-hover rounded-circle',
25
+ success:
26
+ 'bg-success-idle text-white border-success-idle hover:bg-success-hover rounded-circle',
27
+ warning:
28
+ 'bg-warning-idle text-white border-warning-idle hover:bg-warning-hover rounded-circle',
29
+ destructive:
30
+ 'bg-destructive-idle text-white border-destructive-idle hover:bg-destructive-hover rounded-circle',
31
+ neutral:
32
+ 'bg-neutral-dark text-white border-neutral-dark hover:bg-neutral-hover rounded-circle',
33
+ outline:
34
+ 'bg-white text-neutral-dark border-border-layer-2 hover:bg-layer-2-hover rounded-circle'
35
+ },
36
+ position: {
37
+ fixed: 'fixed bottom-6 left-1/2 -translate-x-1/2 transform',
38
+ absolute: 'absolute bottom-6 left-1/2 -translate-x-1/2 transform',
39
+ relative: 'relative',
40
+ sticky: 'sticky bottom-6'
41
+ }
42
+ },
43
+ defaultVariants: {
44
+ size: 'md',
45
+ variant: 'primary',
46
+ position: 'fixed'
47
+ }
48
+ }
49
+ )
50
+
51
+ export interface SelectionAction {
52
+ id: string
53
+ label?: string
54
+ icon: IconType
55
+ onClick: () => void
56
+ variant?: 'primary' | 'secondary' | 'destructive' | 'tertiary' | 'outlined'
57
+ disabled?: boolean
58
+ }
59
+
60
+ interface SelectionBarProps
61
+ extends Omit<ComponentProps<'div'>, 'onClose'>,
62
+ ClassVariantProps<typeof selectionBarVariants> {
63
+ selectedCount: number
64
+ onClose: () => void
65
+ actions?: SelectionAction[]
66
+ showCloseButton?: boolean
67
+ closeButtonText?: string
68
+ selectedText?: string
69
+ className?: string
70
+ }
71
+
72
+ function SelectionBar({
73
+ selectedCount,
74
+ onClose,
75
+ actions = [],
76
+ showCloseButton = true,
77
+ selectedText,
78
+ size = 'md',
79
+ variant = 'primary',
80
+ position = 'fixed',
81
+ className,
82
+ ...props
83
+ }: SelectionBarProps) {
84
+ if (selectedCount === 0) return null
85
+
86
+ const getSelectedText = () => {
87
+ if (selectedText) return selectedText
88
+ return selectedCount === 1
89
+ ? '1 item selecionado'
90
+ : `${selectedCount} itens selecionados`
91
+ }
92
+
93
+ const getIconSize = () => {
94
+ switch (size) {
95
+ case 'sm':
96
+ return 'text-sm'
97
+ case 'md':
98
+ return 'text-base'
99
+ case 'lg':
100
+ return 'text-lg'
101
+ default:
102
+ return 'text-base'
103
+ }
104
+ }
105
+
106
+ return (
107
+ <div
108
+ className={cx(
109
+ selectionBarVariants({ size, variant, position }),
110
+ className
111
+ )}
112
+ {...props}
113
+ >
114
+ {showCloseButton && (
115
+ <Button
116
+ appearance="ghost"
117
+ className="rounded-full text-current"
118
+ size={size === 'lg' ? 'md' : 'sm'}
119
+ variant="secondary"
120
+ onClick={() => onClose()}
121
+ >
122
+ <Icon className={getIconSize()} name="close" />
123
+ </Button>
124
+ )}
125
+
126
+ <span className="font-medium whitespace-nowrap">{getSelectedText()}</span>
127
+
128
+ {actions.map(action => (
129
+ <Button
130
+ appearance="ghost"
131
+ className="rounded-full text-current"
132
+ disabled={action.disabled}
133
+ key={action.id}
134
+ size={size === 'lg' ? 'md' : 'sm'}
135
+ variant={action.variant || 'secondary'}
136
+ onClick={() => action.onClick()}
137
+ >
138
+ <Icon className={getIconSize()} name={action.icon} />
139
+ {action.label && <span className="ml-2">{action.label}</span>}
140
+ </Button>
141
+ ))}
142
+ </div>
143
+ )
144
+ }
145
+
146
+ interface SelectionBarContextType {
147
+ selectedItems: Set<string>
148
+ toggleSelection: (id: string) => void
149
+ clearSelection: () => void
150
+ selectAll: (ids: string[]) => void
151
+ isSelected: (id: string) => boolean
152
+ selectedCount: number
153
+ }
154
+
155
+ const SelectionBarContext = createContext<SelectionBarContextType | null>(null)
156
+
157
+ interface SelectionBarProviderProps {
158
+ children: ReactNode
159
+ onSelectionChange?: (selectedIds: string[]) => void
160
+ }
161
+
162
+ function SelectionBarProvider({
163
+ children,
164
+ onSelectionChange
165
+ }: SelectionBarProviderProps) {
166
+ const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set())
167
+
168
+ const toggleSelection = useCallback(
169
+ (id: string) => {
170
+ setSelectedItems(prev => {
171
+ const newSet = new Set(prev)
172
+ if (newSet.has(id)) {
173
+ newSet.delete(id)
174
+ } else {
175
+ newSet.add(id)
176
+ }
177
+ onSelectionChange?.(Array.from(newSet))
178
+ return newSet
179
+ })
180
+ },
181
+ [onSelectionChange]
182
+ )
183
+
184
+ const clearSelection = useCallback(() => {
185
+ setSelectedItems(new Set())
186
+ onSelectionChange?.([])
187
+ }, [onSelectionChange])
188
+
189
+ const selectAll = useCallback(
190
+ (ids: string[]) => {
191
+ setSelectedItems(new Set(ids))
192
+ onSelectionChange?.(ids)
193
+ },
194
+ [onSelectionChange]
195
+ )
196
+
197
+ const isSelected = useCallback(
198
+ (id: string) => {
199
+ return selectedItems.has(id)
200
+ },
201
+ [selectedItems]
202
+ )
203
+
204
+ const value: SelectionBarContextType = {
205
+ selectedItems,
206
+ toggleSelection,
207
+ clearSelection,
208
+ selectAll,
209
+ isSelected,
210
+ selectedCount: selectedItems.size
211
+ }
212
+
213
+ return (
214
+ <SelectionBarContext.Provider value={value}>
215
+ {children}
216
+ </SelectionBarContext.Provider>
217
+ )
218
+ }
219
+
220
+ function useSelectionBar() {
221
+ const context = useContext(SelectionBarContext)
222
+ if (!context) {
223
+ throw new Error(
224
+ 'useSelectionBar must be used within a SelectionBarProvider'
225
+ )
226
+ }
227
+ return context
228
+ }
229
+
230
+ interface SelectionBarContainerProps
231
+ extends Omit<SelectionBarProps, 'selectedCount' | 'onClose'> {
232
+ showCloseButton?: boolean
233
+ closeButtonText?: string
234
+ selectedText?: string
235
+ }
236
+
237
+ function SelectionBarContainer({
238
+ actions = [],
239
+ showCloseButton = true,
240
+ selectedText,
241
+ ...props
242
+ }: SelectionBarContainerProps) {
243
+ const { selectedCount, clearSelection } = useSelectionBar()
244
+
245
+ return (
246
+ <SelectionBar
247
+ actions={actions}
248
+ selectedCount={selectedCount}
249
+ selectedText={selectedText}
250
+ showCloseButton={showCloseButton}
251
+ onClose={() => clearSelection()}
252
+ {...props}
253
+ />
254
+ )
255
+ }
256
+
257
+ export const SelectionBarComponents = {
258
+ Root: SelectionBar,
259
+ Provider: SelectionBarProvider,
260
+ Container: SelectionBarContainer,
261
+ useSelectionBar
262
+ }
263
+
264
+ export { SelectionBar }
265
+ export { SelectionBarProvider }
266
+ export { SelectionBarContainer }
267
+ export { useSelectionBar }
268
+ export { selectionBarVariants }
269
+ export type {
270
+ SelectionBarProps,
271
+ SelectionBarProviderProps,
272
+ SelectionBarContainerProps
273
+ }
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react'
2
2
  import * as SheetPrimitive from '@radix-ui/react-dialog'
3
3
  import { cx } from '@xjur-ui/util'
4
- import { Button } from './button'
4
+ import { Button } from './form/button'
5
5
  import { Icon } from './icon'
6
6
 
7
7
  export function SheetRoot({
@@ -44,7 +44,7 @@ export function SheetOverlay({
44
44
  return (
45
45
  <SheetPrimitive.Overlay
46
46
  className={cx(
47
- 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
47
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50',
48
48
  className
49
49
  )}
50
50
  data-slot="sheet-overlay"