maquinaweb-ui 2.64.0 → 2.65.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 (226) hide show
  1. package/dist/_virtual/rolldown_runtime.js +30 -0
  2. package/dist/container-animation/container-animation.d.ts +29 -0
  3. package/dist/container-animation/container-animation.d.ts.map +1 -0
  4. package/dist/container-animation/container-animation.js +57 -0
  5. package/dist/container-animation/container-animation.js.map +1 -0
  6. package/dist/container-animation.d.ts +2 -29
  7. package/dist/container-animation.js +2 -128
  8. package/dist/date-field/DateField.d.ts +35 -0
  9. package/dist/date-field/DateField.d.ts.map +1 -0
  10. package/dist/date-field/DateField.js +99 -0
  11. package/dist/date-field/DateField.js.map +1 -0
  12. package/dist/date-field.d.ts +2 -35
  13. package/dist/date-field.js +2 -96
  14. package/dist/date-hour-field/DateHourField.d.ts +35 -0
  15. package/dist/date-hour-field/DateHourField.d.ts.map +1 -0
  16. package/dist/date-hour-field/DateHourField.js +208 -0
  17. package/dist/date-hour-field/DateHourField.js.map +1 -0
  18. package/dist/date-hour-field/date-hour-field.utils.js +78 -0
  19. package/dist/date-hour-field/date-hour-field.utils.js.map +1 -0
  20. package/dist/date-hour-field/time-wheel-column.js +59 -0
  21. package/dist/date-hour-field/time-wheel-column.js.map +1 -0
  22. package/dist/date-hour-field.d.ts +2 -35
  23. package/dist/date-hour-field.js +2 -329
  24. package/dist/input-suggest/input-suggest.d.ts +77 -0
  25. package/dist/input-suggest/input-suggest.d.ts.map +1 -0
  26. package/dist/input-suggest/input-suggest.js +188 -0
  27. package/dist/input-suggest/input-suggest.js.map +1 -0
  28. package/dist/input-suggest.d.ts +2 -77
  29. package/dist/input-suggest.js +2 -183
  30. package/dist/kanban-dnd/constants.js +28 -0
  31. package/dist/kanban-dnd/constants.js.map +1 -0
  32. package/dist/kanban-dnd/context.d.ts +23 -0
  33. package/dist/kanban-dnd/context.d.ts.map +1 -0
  34. package/dist/kanban-dnd/context.js +62 -0
  35. package/dist/kanban-dnd/context.js.map +1 -0
  36. package/dist/kanban-dnd/drag-preview.js +58 -0
  37. package/dist/kanban-dnd/drag-preview.js.map +1 -0
  38. package/dist/kanban-dnd/drop-animation.js +129 -0
  39. package/dist/kanban-dnd/drop-animation.js.map +1 -0
  40. package/dist/kanban-dnd/kanban-card-item.d.ts +14 -0
  41. package/dist/kanban-dnd/kanban-card-item.d.ts.map +1 -0
  42. package/dist/kanban-dnd/kanban-card-item.js +72 -0
  43. package/dist/kanban-dnd/kanban-card-item.js.map +1 -0
  44. package/dist/kanban-dnd/kanban-dnd-monitor.d.ts +29 -0
  45. package/dist/kanban-dnd/kanban-dnd-monitor.d.ts.map +1 -0
  46. package/dist/kanban-dnd/kanban-dnd-monitor.js +292 -0
  47. package/dist/kanban-dnd/kanban-dnd-monitor.js.map +1 -0
  48. package/dist/kanban-dnd/kanban-dnd.d.ts +8 -0
  49. package/dist/kanban-dnd/kanban-dropzone.d.ts +13 -0
  50. package/dist/kanban-dnd/kanban-dropzone.d.ts.map +1 -0
  51. package/dist/kanban-dnd/kanban-dropzone.js +38 -0
  52. package/dist/kanban-dnd/kanban-dropzone.js.map +1 -0
  53. package/dist/kanban-dnd/kanban-selector.d.ts +12 -0
  54. package/dist/kanban-dnd/kanban-selector.d.ts.map +1 -0
  55. package/dist/kanban-dnd/kanban-selector.js +113 -0
  56. package/dist/kanban-dnd/kanban-selector.js.map +1 -0
  57. package/dist/kanban-dnd/move-cards.d.ts +11 -0
  58. package/dist/kanban-dnd/move-cards.d.ts.map +1 -0
  59. package/dist/kanban-dnd/move-cards.js +67 -0
  60. package/dist/kanban-dnd/move-cards.js.map +1 -0
  61. package/dist/kanban-dnd/types.d.ts +73 -0
  62. package/dist/kanban-dnd/types.d.ts.map +1 -0
  63. package/dist/kanban-dnd/use-kanban-column-dnd.d.ts +11 -0
  64. package/dist/kanban-dnd/use-kanban-column-dnd.d.ts.map +1 -0
  65. package/dist/kanban-dnd/use-kanban-column-dnd.js +37 -0
  66. package/dist/kanban-dnd/use-kanban-column-dnd.js.map +1 -0
  67. package/dist/kanban-dnd/use-kanban-selector-auto-scroll.js +127 -0
  68. package/dist/kanban-dnd/use-kanban-selector-auto-scroll.js.map +1 -0
  69. package/dist/kanban-dnd/utils.js +12 -0
  70. package/dist/kanban-dnd/utils.js.map +1 -0
  71. package/dist/kanban-dnd.d.ts +10 -155
  72. package/dist/kanban-dnd.js +9 -959
  73. package/dist/landing-content.d.ts +2 -0
  74. package/dist/landing-content.js +3 -0
  75. package/dist/landing-text/client-landing-text.js +119 -0
  76. package/dist/landing-text/client-landing-text.js.map +1 -0
  77. package/dist/landing-text/landing-content.d.ts +55 -0
  78. package/dist/landing-text/landing-content.d.ts.map +1 -0
  79. package/dist/landing-text/landing-content.js +112 -0
  80. package/dist/landing-text/landing-content.js.map +1 -0
  81. package/dist/landing-text/landing-text.d.ts +26 -0
  82. package/dist/landing-text/landing-text.d.ts.map +1 -0
  83. package/dist/landing-text/landing-text.js +34 -0
  84. package/dist/landing-text/landing-text.js.map +1 -0
  85. package/dist/landing-text/server-landing-text.d.ts +24 -0
  86. package/dist/landing-text/server-landing-text.d.ts.map +1 -0
  87. package/dist/landing-text/server-landing-text.js +18 -0
  88. package/dist/landing-text/server-landing-text.js.map +1 -0
  89. package/dist/landing-text.d.ts +3 -96
  90. package/dist/landing-text.js +3 -950
  91. package/dist/node_modules/cookie/dist/index.js +300 -0
  92. package/dist/node_modules/cookie/dist/index.js.map +1 -0
  93. package/dist/node_modules/cookies-next/lib/client/context.js +111 -0
  94. package/dist/node_modules/cookies-next/lib/client/context.js.map +1 -0
  95. package/dist/node_modules/cookies-next/lib/client/cookie-functions.js +85 -0
  96. package/dist/node_modules/cookies-next/lib/client/cookie-functions.js.map +1 -0
  97. package/dist/node_modules/cookies-next/lib/client/hooks.js +129 -0
  98. package/dist/node_modules/cookies-next/lib/client/hooks.js.map +1 -0
  99. package/dist/node_modules/cookies-next/lib/client/index.js +44 -0
  100. package/dist/node_modules/cookies-next/lib/client/index.js.map +1 -0
  101. package/dist/node_modules/cookies-next/lib/common/types.js +12 -0
  102. package/dist/node_modules/cookies-next/lib/common/types.js.map +1 -0
  103. package/dist/node_modules/cookies-next/lib/common/utils.js +35 -0
  104. package/dist/node_modules/cookies-next/lib/common/utils.js.map +1 -0
  105. package/dist/node_modules/framer-motion/dist/es/render/dom/viewport/index.js +40 -0
  106. package/dist/node_modules/framer-motion/dist/es/render/dom/viewport/index.js.map +1 -0
  107. package/dist/node_modules/framer-motion/dist/es/utils/use-in-view.js +34 -0
  108. package/dist/node_modules/framer-motion/dist/es/utils/use-in-view.js.map +1 -0
  109. package/dist/node_modules/motion-dom/dist/es/utils/resolve-elements.js +16 -0
  110. package/dist/node_modules/motion-dom/dist/es/utils/resolve-elements.js.map +1 -0
  111. package/dist/page-header/page-header.d.ts +16 -0
  112. package/dist/page-header/page-header.d.ts.map +1 -0
  113. package/dist/page-header/page-header.js +23 -0
  114. package/dist/page-header/page-header.js.map +1 -0
  115. package/dist/page-header.d.ts +2 -16
  116. package/dist/page-header.js +2 -24
  117. package/dist/remote-selector/remote-selector.d.ts +64 -0
  118. package/dist/remote-selector/remote-selector.d.ts.map +1 -0
  119. package/dist/remote-selector/remote-selector.js +114 -0
  120. package/dist/remote-selector/remote-selector.js.map +1 -0
  121. package/dist/remote-selector.d.ts +2 -107
  122. package/dist/remote-selector.js +2 -575
  123. package/dist/split-text-poor/split-text-poor.d.ts +59 -0
  124. package/dist/split-text-poor/split-text-poor.d.ts.map +1 -0
  125. package/dist/split-text-poor/split-text-poor.js +79 -0
  126. package/dist/split-text-poor/split-text-poor.js.map +1 -0
  127. package/dist/split-text-poor.d.ts +2 -59
  128. package/dist/split-text-poor.js +2 -75
  129. package/dist/src/hooks/get-mask-options.js +91 -0
  130. package/dist/src/hooks/get-mask-options.js.map +1 -0
  131. package/dist/src/hooks/is-server.js +7 -0
  132. package/dist/src/hooks/is-server.js.map +1 -0
  133. package/dist/src/hooks/module-interop.js +15 -0
  134. package/dist/src/hooks/module-interop.js.map +1 -0
  135. package/dist/src/hooks/use-money-input.js +39 -0
  136. package/dist/src/hooks/use-money-input.js.map +1 -0
  137. package/dist/{with-mask-BLZS7b9k.d.ts → src/hooks/with-mask.d.ts} +2 -2
  138. package/dist/src/hooks/with-mask.d.ts.map +1 -0
  139. package/dist/src/hooks/with-mask.js +16 -0
  140. package/dist/src/hooks/with-mask.js.map +1 -0
  141. package/dist/{utils-C8_amEgK.js → src/lib/utils.js} +2 -2
  142. package/dist/src/lib/utils.js.map +1 -0
  143. package/dist/text-field/TextField.d.ts +103 -0
  144. package/dist/text-field/TextField.d.ts.map +1 -0
  145. package/dist/text-field/TextField.js +198 -0
  146. package/dist/text-field/TextField.js.map +1 -0
  147. package/dist/text-field.d.ts +2 -103
  148. package/dist/text-field.js +2 -223
  149. package/dist/toggle-field/ToggleField.d.ts +19 -0
  150. package/dist/toggle-field/ToggleField.d.ts.map +1 -0
  151. package/dist/toggle-field/ToggleField.js +47 -0
  152. package/dist/toggle-field/ToggleField.js.map +1 -0
  153. package/dist/toggle-field/ToggleGroup.d.ts +34 -0
  154. package/dist/toggle-field/ToggleGroup.d.ts.map +1 -0
  155. package/dist/toggle-field/ToggleGroup.js +128 -0
  156. package/dist/toggle-field/ToggleGroup.js.map +1 -0
  157. package/dist/toggle-field.d.ts +2 -49
  158. package/dist/toggle-field.js +2 -162
  159. package/dist/ui/badge.js +26 -0
  160. package/dist/ui/badge.js.map +1 -0
  161. package/dist/{button-B3nLhVyZ.js → ui/button.js} +3 -3
  162. package/dist/ui/button.js.map +1 -0
  163. package/dist/{input-date-field-DToF0FmE.js → ui/calendar.js} +8 -51
  164. package/dist/ui/calendar.js.map +1 -0
  165. package/dist/ui/checkbox.js +71 -0
  166. package/dist/ui/checkbox.js.map +1 -0
  167. package/dist/ui/command.js +60 -0
  168. package/dist/ui/command.js.map +1 -0
  169. package/dist/ui/content-help.js +27 -0
  170. package/dist/ui/content-help.js.map +1 -0
  171. package/dist/ui/form.js +82 -0
  172. package/dist/ui/form.js.map +1 -0
  173. package/dist/ui/input-date-field.js +52 -0
  174. package/dist/ui/input-date-field.js.map +1 -0
  175. package/dist/ui/input-help.js +27 -0
  176. package/dist/ui/input-help.js.map +1 -0
  177. package/dist/ui/input.js +16 -0
  178. package/dist/ui/input.js.map +1 -0
  179. package/dist/{label-Bkg7B2j8.js → ui/label.js} +6 -3
  180. package/dist/ui/label.js.map +1 -0
  181. package/dist/{popover-D9IIn0lW.js → ui/popover.js} +6 -3
  182. package/dist/ui/popover.js.map +1 -0
  183. package/dist/{scroll-area-C1kW_eA9.js → ui/scroll-area.js} +6 -3
  184. package/dist/ui/scroll-area.js.map +1 -0
  185. package/dist/ui/selector.d.ts +48 -0
  186. package/dist/ui/selector.d.ts.map +1 -0
  187. package/dist/ui/selector.js +243 -0
  188. package/dist/ui/selector.js.map +1 -0
  189. package/dist/ui/tooltip.js +41 -0
  190. package/dist/ui/tooltip.js.map +1 -0
  191. package/dist/ui/tree-item-renderer.js +114 -0
  192. package/dist/ui/tree-item-renderer.js.map +1 -0
  193. package/package.json +5 -1
  194. package/dist/button-B3nLhVyZ.js.map +0 -1
  195. package/dist/container-animation.d.ts.map +0 -1
  196. package/dist/container-animation.js.map +0 -1
  197. package/dist/date-field.d.ts.map +0 -1
  198. package/dist/date-field.js.map +0 -1
  199. package/dist/date-hour-field.d.ts.map +0 -1
  200. package/dist/date-hour-field.js.map +0 -1
  201. package/dist/input-Bs61WBGW.js +0 -133
  202. package/dist/input-Bs61WBGW.js.map +0 -1
  203. package/dist/input-date-field-DToF0FmE.js.map +0 -1
  204. package/dist/input-help-D1JqF0YH.js +0 -149
  205. package/dist/input-help-D1JqF0YH.js.map +0 -1
  206. package/dist/input-suggest.d.ts.map +0 -1
  207. package/dist/input-suggest.js.map +0 -1
  208. package/dist/kanban-dnd.d.ts.map +0 -1
  209. package/dist/kanban-dnd.js.map +0 -1
  210. package/dist/label-Bkg7B2j8.js.map +0 -1
  211. package/dist/landing-text.d.ts.map +0 -1
  212. package/dist/landing-text.js.map +0 -1
  213. package/dist/page-header.d.ts.map +0 -1
  214. package/dist/page-header.js.map +0 -1
  215. package/dist/popover-D9IIn0lW.js.map +0 -1
  216. package/dist/remote-selector.d.ts.map +0 -1
  217. package/dist/remote-selector.js.map +0 -1
  218. package/dist/scroll-area-C1kW_eA9.js.map +0 -1
  219. package/dist/split-text-poor.d.ts.map +0 -1
  220. package/dist/split-text-poor.js.map +0 -1
  221. package/dist/text-field.d.ts.map +0 -1
  222. package/dist/text-field.js.map +0 -1
  223. package/dist/toggle-field.d.ts.map +0 -1
  224. package/dist/toggle-field.js.map +0 -1
  225. package/dist/utils-C8_amEgK.js.map +0 -1
  226. package/dist/with-mask-BLZS7b9k.d.ts.map +0 -1
@@ -0,0 +1,208 @@
1
+ 'use client';
2
+
3
+
4
+ import { cn } from "../src/lib/utils.js";
5
+ import withMask from "../src/hooks/with-mask.js";
6
+ import { FormDescription, FormFieldContext, FormItem, FormLabel, FormMessage } from "../ui/form.js";
7
+ import { Input } from "../ui/input.js";
8
+ import { InputHelp } from "../ui/input-help.js";
9
+ import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover.js";
10
+ import { Calendar } from "../ui/calendar.js";
11
+ import { InputDateField } from "../ui/input-date-field.js";
12
+ import { HOUR_OPTIONS, MINUTE_OPTIONS, formatDateTimeAsLocalString, formatDateTimeAsTime, formatTimeValue, getFallbackTime, mergeDateAndTime, normalizeDateValue, parseTime, sanitizeTimeInput } from "./date-hour-field.utils.js";
13
+ import { TimeWheelColumn } from "./time-wheel-column.js";
14
+ import { useController, useFormContext } from "react-hook-form";
15
+ import { useEffect, useState } from "react";
16
+ import { jsx, jsxs } from "react/jsx-runtime";
17
+ import { ptBR } from "date-fns/locale";
18
+
19
+ //#region src/components/date-hour-field/DateHourField.tsx
20
+ function DateHourField({ name, label, description, inputDisabled, endMonth, className, disabled, initialValue, required, help, hourPlaceholder = "Hora", valueType = "local-string" }) {
21
+ const form = useFormContext();
22
+ const { field, fieldState } = useController({
23
+ name,
24
+ defaultValue: initialValue,
25
+ rules: { required },
26
+ control: form.control
27
+ });
28
+ const [isOpen, setIsOpen] = useState(false);
29
+ const [timeValue, setTimeValue] = useState("");
30
+ const valueAsDate = normalizeDateValue(field.value);
31
+ const selectedTime = parseTime(timeValue);
32
+ useEffect(() => {
33
+ if (!valueAsDate) {
34
+ setTimeValue("");
35
+ return;
36
+ }
37
+ const nextValue = formatDateTimeAsTime(valueAsDate);
38
+ setTimeValue((currentValue) => currentValue === nextValue ? currentValue : nextValue);
39
+ }, [valueAsDate]);
40
+ const updateFieldTime = (timePatch) => {
41
+ const fallbackTime = getFallbackTime(valueAsDate);
42
+ const baseTime = selectedTime ?? fallbackTime;
43
+ const nextTime = {
44
+ hours: baseTime.hours,
45
+ minutes: baseTime.minutes,
46
+ ...timePatch
47
+ };
48
+ const nextDate = new Date(valueAsDate ?? /* @__PURE__ */ new Date());
49
+ nextDate.setHours(nextTime.hours, nextTime.minutes, 0, 0);
50
+ setTimeValue(formatTimeValue(nextTime.hours, nextTime.minutes));
51
+ if (valueType === "local-string") {
52
+ field.onChange(formatDateTimeAsLocalString(nextDate));
53
+ return;
54
+ }
55
+ field.onChange(nextDate);
56
+ };
57
+ const handleDateSelect = (date) => {
58
+ if (!date) {
59
+ setTimeValue("");
60
+ field.onChange(void 0);
61
+ return;
62
+ }
63
+ const mergedDate = mergeDateAndTime(date, timeValue, valueAsDate);
64
+ setTimeValue(formatDateTimeAsTime(mergedDate));
65
+ if (valueType === "local-string") {
66
+ field.onChange(formatDateTimeAsLocalString(mergedDate));
67
+ return;
68
+ }
69
+ field.onChange(mergedDate);
70
+ };
71
+ const handleTimeInputChange = (nextValue) => {
72
+ const sanitizedValue = sanitizeTimeInput(nextValue);
73
+ setTimeValue(sanitizedValue);
74
+ if (sanitizedValue.length !== 5) return;
75
+ const parsedTime = parseTime(sanitizedValue);
76
+ if (!parsedTime) return;
77
+ updateFieldTime(parsedTime);
78
+ };
79
+ const handleHourSelect = (hourLabel) => {
80
+ const selectedHourValue = Number(hourLabel);
81
+ if (Number.isNaN(selectedHourValue)) return;
82
+ updateFieldTime({ hours: selectedHourValue });
83
+ };
84
+ const handleMinuteSelect = (minuteLabel) => {
85
+ const selectedMinuteValue = Number(minuteLabel);
86
+ if (Number.isNaN(selectedMinuteValue)) return;
87
+ updateFieldTime({ minutes: selectedMinuteValue });
88
+ };
89
+ return /* @__PURE__ */ jsx(FormFieldContext.Provider, {
90
+ value: { name },
91
+ children: /* @__PURE__ */ jsxs(FormItem, {
92
+ className,
93
+ id: `date-hour-${name.replace(".", "-")}`,
94
+ children: [
95
+ /* @__PURE__ */ jsxs("div", {
96
+ className: "flex items-end gap-1.5",
97
+ children: [/* @__PURE__ */ jsxs(FormLabel, {
98
+ htmlFor: name,
99
+ children: [
100
+ label,
101
+ ":",
102
+ required && /* @__PURE__ */ jsx("span", {
103
+ className: "text-red-500 text-lg leading-px",
104
+ children: "*"
105
+ })
106
+ ]
107
+ }), /* @__PURE__ */ jsx(InputHelp, {
108
+ help,
109
+ name
110
+ })]
111
+ }),
112
+ /* @__PURE__ */ jsxs(Popover, {
113
+ modal: true,
114
+ onOpenChange: setIsOpen,
115
+ open: !inputDisabled && isOpen,
116
+ children: [/* @__PURE__ */ jsx(PopoverTrigger, {
117
+ asChild: true,
118
+ children: /* @__PURE__ */ jsxs("div", {
119
+ className: "flex w-full items-center",
120
+ onClick: (event) => {
121
+ event.preventDefault();
122
+ event.stopPropagation();
123
+ },
124
+ children: [/* @__PURE__ */ jsx("div", {
125
+ className: "w-full",
126
+ children: /* @__PURE__ */ jsx(InputDateField, {
127
+ className: cn("border-r-0! rounded-r-none", fieldState.error && "border-destructive"),
128
+ disabled: inputDisabled,
129
+ field: {
130
+ ...field,
131
+ onChange(nextValue) {
132
+ const normalizedDate = normalizeDateValue(nextValue);
133
+ if (!normalizedDate) {
134
+ setTimeValue("");
135
+ field.onChange(void 0);
136
+ return;
137
+ }
138
+ const mergedDate = mergeDateAndTime(normalizedDate, timeValue, valueAsDate);
139
+ setTimeValue(formatDateTimeAsTime(mergedDate));
140
+ if (valueType === "local-string") {
141
+ field.onChange(formatDateTimeAsLocalString(mergedDate));
142
+ return;
143
+ }
144
+ field.onChange(mergedDate);
145
+ },
146
+ value: valueAsDate
147
+ },
148
+ id: name,
149
+ onFocus: () => setIsOpen(true)
150
+ })
151
+ }), /* @__PURE__ */ jsx(Input, {
152
+ className: cn("w-28 min-w-28 border-l rounded-l-none", fieldState.error && "border-destructive"),
153
+ disabled: inputDisabled,
154
+ id: `${name}-hour`,
155
+ onChange: (event) => handleTimeInputChange(event.target.value),
156
+ onFocus: () => setIsOpen(true),
157
+ placeholder: hourPlaceholder,
158
+ ref: withMask("99:99", {
159
+ clearMaskOnLostFocus: true,
160
+ showMaskOnFocus: false,
161
+ showMaskOnHover: false,
162
+ undoOnEscape: false
163
+ }),
164
+ value: timeValue
165
+ })]
166
+ })
167
+ }), /* @__PURE__ */ jsxs(PopoverContent, {
168
+ className: "flex w-fit gap-2 p-0 items-center",
169
+ onOpenAutoFocus: (event) => event.preventDefault(),
170
+ children: [/* @__PURE__ */ jsx(Calendar, {
171
+ defaultMonth: valueAsDate || /* @__PURE__ */ new Date(),
172
+ disabled,
173
+ endMonth,
174
+ locale: ptBR,
175
+ mode: "single",
176
+ onSelect: handleDateSelect,
177
+ selected: valueAsDate
178
+ }, `${name}-${valueAsDate?.toString()}-${timeValue}`), /* @__PURE__ */ jsx("div", {
179
+ className: "relative shrink-0 my-auto border-l p-3 pr-3 ",
180
+ children: /* @__PURE__ */ jsxs("div", {
181
+ className: "flex gap-2",
182
+ children: [/* @__PURE__ */ jsx(TimeWheelColumn, {
183
+ isOpen,
184
+ label: "Hora",
185
+ onSelect: handleHourSelect,
186
+ options: HOUR_OPTIONS,
187
+ selectedValue: selectedTime?.hours
188
+ }), /* @__PURE__ */ jsx(TimeWheelColumn, {
189
+ isOpen,
190
+ label: "Min",
191
+ onSelect: handleMinuteSelect,
192
+ options: MINUTE_OPTIONS,
193
+ selectedValue: selectedTime?.minutes
194
+ })]
195
+ })
196
+ })]
197
+ })]
198
+ }),
199
+ /* @__PURE__ */ jsx(FormDescription, { children: description }),
200
+ fieldState.error && /* @__PURE__ */ jsx(FormMessage, {})
201
+ ]
202
+ })
203
+ });
204
+ }
205
+
206
+ //#endregion
207
+ export { DateHourField };
208
+ //# sourceMappingURL=DateHourField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateHourField.js","names":[],"sources":["../../src/components/date-hour-field/DateHourField.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState } from 'react';\n\nimport {\n type FieldPath,\n type FieldValues,\n type UseControllerProps,\n useController,\n useFormContext,\n} from 'react-hook-form';\nimport withMask from '@/hooks/with-mask';\n\nimport { Calendar } from '@/ui/calendar';\nimport {\n FormDescription,\n FormFieldContext,\n FormItem,\n FormLabel,\n FormMessage,\n} from '@/ui/form';\nimport { Input } from '@/ui/input';\nimport { InputDateField } from '@/ui/input-date-field';\nimport { InputHelp } from '@/ui/input-help';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/ui/popover';\n\nimport { cn } from '@/lib/utils';\nimport { ptBR } from 'date-fns/locale';\nimport type { Matcher } from 'react-day-picker';\nimport {\n type ParsedTime,\n HOUR_OPTIONS,\n MINUTE_OPTIONS,\n formatDateTimeAsTime,\n formatDateTimeAsLocalString,\n formatTimeValue,\n getFallbackTime,\n mergeDateAndTime,\n normalizeDateValue,\n parseTime,\n sanitizeTimeInput,\n} from './date-hour-field.utils';\nimport { TimeWheelColumn } from './time-wheel-column';\n\nexport interface DateHourFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> extends Omit<UseControllerProps<TFieldValues, TFieldName>, 'disabled'> {\n label: string;\n description?: string;\n className?: string;\n disabled?: Matcher | Matcher[] | undefined;\n inputDisabled?: boolean;\n initialValue?: Date;\n endMonth?: Date;\n required?: boolean;\n help?: string;\n hourPlaceholder?: string;\n valueType?: 'date' | 'local-string';\n}\n\nfunction DateHourField<\n TFieldValues extends FieldValues = FieldValues,\n TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n name,\n label,\n description,\n inputDisabled,\n endMonth,\n className,\n disabled,\n initialValue,\n required,\n help,\n hourPlaceholder = 'Hora',\n valueType = 'local-string',\n}: DateHourFieldProps<TFieldValues, TFieldName>) {\n const form = useFormContext();\n const { field, fieldState } = useController({\n name,\n defaultValue: initialValue as any,\n rules: { required },\n control: form.control,\n });\n\n const [isOpen, setIsOpen] = useState(false);\n const [timeValue, setTimeValue] = useState('');\n\n const valueAsDate = normalizeDateValue(field.value);\n const selectedTime = parseTime(timeValue);\n\n useEffect(() => {\n if (!valueAsDate) {\n setTimeValue('');\n return;\n }\n\n const nextValue = formatDateTimeAsTime(valueAsDate);\n setTimeValue((currentValue) =>\n currentValue === nextValue ? currentValue : nextValue\n );\n }, [valueAsDate]);\n\n const updateFieldTime = (timePatch: Partial<ParsedTime>) => {\n const fallbackTime = getFallbackTime(valueAsDate);\n const baseTime = selectedTime ?? fallbackTime;\n\n const nextTime = {\n hours: baseTime.hours,\n minutes: baseTime.minutes,\n ...timePatch,\n };\n\n const nextDate = new Date(valueAsDate ?? new Date());\n nextDate.setHours(nextTime.hours, nextTime.minutes, 0, 0);\n\n setTimeValue(formatTimeValue(nextTime.hours, nextTime.minutes));\n if (valueType === 'local-string') {\n field.onChange(formatDateTimeAsLocalString(nextDate));\n return;\n }\n\n field.onChange(nextDate);\n };\n\n const handleDateSelect = (date: Date | undefined) => {\n if (!date) {\n setTimeValue('');\n field.onChange(undefined);\n return;\n }\n\n const mergedDate = mergeDateAndTime(date, timeValue, valueAsDate);\n setTimeValue(formatDateTimeAsTime(mergedDate));\n if (valueType === 'local-string') {\n field.onChange(formatDateTimeAsLocalString(mergedDate));\n return;\n }\n\n field.onChange(mergedDate);\n };\n\n const handleTimeInputChange = (nextValue: string) => {\n const sanitizedValue = sanitizeTimeInput(nextValue);\n setTimeValue(sanitizedValue);\n\n if (sanitizedValue.length !== 5) return;\n\n const parsedTime = parseTime(sanitizedValue);\n if (!parsedTime) return;\n\n updateFieldTime(parsedTime);\n };\n\n const handleHourSelect = (hourLabel: string) => {\n const selectedHourValue = Number(hourLabel);\n if (Number.isNaN(selectedHourValue)) return;\n\n updateFieldTime({ hours: selectedHourValue });\n };\n\n const handleMinuteSelect = (minuteLabel: string) => {\n const selectedMinuteValue = Number(minuteLabel);\n if (Number.isNaN(selectedMinuteValue)) return;\n\n updateFieldTime({ minutes: selectedMinuteValue });\n };\n\n return (\n <FormFieldContext.Provider value={{ name }}>\n <FormItem\n className={className}\n id={`date-hour-${name.replace('.', '-')}`}\n >\n <div className=\"flex items-end gap-1.5\">\n <FormLabel htmlFor={name}>\n {label}:\n {required && (\n <span className=\"text-red-500 text-lg leading-px\">*</span>\n )}\n </FormLabel>\n\n <InputHelp help={help} name={name} />\n </div>\n\n <Popover modal onOpenChange={setIsOpen} open={!inputDisabled && isOpen}>\n <PopoverTrigger asChild>\n <div\n className=\"flex w-full items-center\"\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n >\n <div className=\"w-full\">\n <InputDateField\n className={cn(\n 'border-r-0! rounded-r-none',\n fieldState.error && 'border-destructive'\n )}\n disabled={inputDisabled}\n field={{\n ...field,\n onChange(nextValue) {\n const normalizedDate = normalizeDateValue(nextValue);\n if (!normalizedDate) {\n setTimeValue('');\n field.onChange(undefined);\n return;\n }\n\n const mergedDate = mergeDateAndTime(\n normalizedDate,\n timeValue,\n valueAsDate\n );\n\n setTimeValue(formatDateTimeAsTime(mergedDate));\n if (valueType === 'local-string') {\n field.onChange(formatDateTimeAsLocalString(mergedDate));\n return;\n }\n\n field.onChange(mergedDate);\n },\n value: valueAsDate,\n }}\n id={name}\n onFocus={() => setIsOpen(true)}\n />\n </div>\n\n <Input\n className={cn(\n 'w-28 min-w-28 border-l rounded-l-none',\n fieldState.error && 'border-destructive'\n )}\n disabled={inputDisabled}\n id={`${name}-hour`}\n onChange={(event) => handleTimeInputChange(event.target.value)}\n onFocus={() => setIsOpen(true)}\n placeholder={hourPlaceholder}\n ref={\n withMask('99:99', {\n clearMaskOnLostFocus: true,\n showMaskOnFocus: false,\n showMaskOnHover: false,\n undoOnEscape: false,\n }) as any\n }\n value={timeValue}\n />\n </div>\n </PopoverTrigger>\n\n <PopoverContent\n className=\"flex w-fit gap-2 p-0 items-center\"\n onOpenAutoFocus={(event) => event.preventDefault()}\n >\n <Calendar\n defaultMonth={valueAsDate || new Date()}\n disabled={disabled}\n endMonth={endMonth}\n key={`${name}-${valueAsDate?.toString()}-${timeValue}`}\n locale={ptBR}\n mode=\"single\"\n onSelect={handleDateSelect}\n selected={valueAsDate}\n />\n\n <div className=\"relative shrink-0 my-auto border-l p-3 pr-3 \">\n <div className=\"flex gap-2\">\n <TimeWheelColumn\n isOpen={isOpen}\n label=\"Hora\"\n onSelect={handleHourSelect}\n options={HOUR_OPTIONS}\n selectedValue={selectedTime?.hours}\n />\n\n <TimeWheelColumn\n isOpen={isOpen}\n label=\"Min\"\n onSelect={handleMinuteSelect}\n options={MINUTE_OPTIONS}\n selectedValue={selectedTime?.minutes}\n />\n </div>\n </div>\n </PopoverContent>\n </Popover>\n\n <FormDescription>{description}</FormDescription>\n {fieldState.error && <FormMessage />}\n </FormItem>\n </FormFieldContext.Provider>\n );\n}\n\nexport { DateHourField };\n"],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ import { format, isValid, parse, parseISO } from "date-fns";
2
+
3
+ //#region src/components/date-hour-field/date-hour-field.utils.ts
4
+ const HOUR_OPTIONS = Array.from({ length: 24 }, (_, index) => String(index).padStart(2, "0"));
5
+ const MINUTE_OPTIONS = Array.from({ length: 60 }, (_, index) => String(index).padStart(2, "0"));
6
+ const parseTime = (value) => {
7
+ const match = value.match(/^(\d{2}):(\d{2})$/);
8
+ if (!match) return void 0;
9
+ const hours = Number(match[1]);
10
+ const minutes = Number(match[2]);
11
+ if (Number.isNaN(hours) || Number.isNaN(minutes) || hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return;
12
+ return {
13
+ hours,
14
+ minutes
15
+ };
16
+ };
17
+ const sanitizeTimeInput = (value) => {
18
+ const [hoursRaw = "", minutesRaw = ""] = value.split(":");
19
+ const hasColon = value.includes(":");
20
+ let hours = hoursRaw;
21
+ let minutes = minutesRaw;
22
+ if (hours.length === 2) {
23
+ const parsedHours = Number(hours);
24
+ if (!Number.isNaN(parsedHours) && parsedHours > 23) hours = "23";
25
+ }
26
+ if (minutes.length === 2) {
27
+ const parsedMinutes = Number(minutes);
28
+ if (!Number.isNaN(parsedMinutes) && parsedMinutes > 59) minutes = "59";
29
+ }
30
+ if (!hasColon) return hours;
31
+ return `${hours}:${minutes}`;
32
+ };
33
+ const normalizeDateValue = (value) => {
34
+ if (!value) return void 0;
35
+ if (value instanceof Date) return isValid(value) ? value : void 0;
36
+ if (typeof value === "string") {
37
+ const parsedLocalDateTimeWithSeconds = parse(value, "yyyy-MM-dd HH:mm:ss", /* @__PURE__ */ new Date());
38
+ if (isValid(parsedLocalDateTimeWithSeconds)) return parsedLocalDateTimeWithSeconds;
39
+ const parsedLocalDateTime = parse(value, "yyyy-MM-dd HH:mm", /* @__PURE__ */ new Date());
40
+ if (isValid(parsedLocalDateTime)) return parsedLocalDateTime;
41
+ const parsedIso = parseISO(value);
42
+ if (isValid(parsedIso)) return parsedIso;
43
+ const parsedDateOnly = parse(value, "yyyy-MM-dd", /* @__PURE__ */ new Date());
44
+ if (isValid(parsedDateOnly)) return parsedDateOnly;
45
+ const parsedAsDate = new Date(value);
46
+ if (isValid(parsedAsDate)) return parsedAsDate;
47
+ }
48
+ };
49
+ const formatTimeValue = (hours, minutes) => {
50
+ return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
51
+ };
52
+ const formatDateTimeAsTime = (date) => {
53
+ return formatTimeValue(date.getHours(), date.getMinutes());
54
+ };
55
+ const formatDateTimeAsLocalString = (date) => {
56
+ return format(date, "yyyy-MM-dd HH:mm:ss");
57
+ };
58
+ const getFallbackTime = (fallbackDate) => {
59
+ if (fallbackDate) return {
60
+ hours: fallbackDate.getHours(),
61
+ minutes: fallbackDate.getMinutes()
62
+ };
63
+ const now = /* @__PURE__ */ new Date();
64
+ return {
65
+ hours: now.getHours(),
66
+ minutes: now.getMinutes()
67
+ };
68
+ };
69
+ const mergeDateAndTime = (selectedDate, timeValue, fallbackDate) => {
70
+ const mergedDate = new Date(selectedDate);
71
+ const parsedTime = parseTime(timeValue) ?? getFallbackTime(fallbackDate);
72
+ mergedDate.setHours(parsedTime.hours, parsedTime.minutes, 0, 0);
73
+ return mergedDate;
74
+ };
75
+
76
+ //#endregion
77
+ export { HOUR_OPTIONS, MINUTE_OPTIONS, formatDateTimeAsLocalString, formatDateTimeAsTime, formatTimeValue, getFallbackTime, mergeDateAndTime, normalizeDateValue, parseTime, sanitizeTimeInput };
78
+ //# sourceMappingURL=date-hour-field.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-hour-field.utils.js","names":[],"sources":["../../src/components/date-hour-field/date-hour-field.utils.ts"],"sourcesContent":["import { format, isValid, parse, parseISO } from 'date-fns';\n\nexport type ParsedTime = {\n hours: number;\n minutes: number;\n};\n\nexport const HOUR_OPTIONS = Array.from({ length: 24 }, (_, index) =>\n String(index).padStart(2, '0')\n);\n\nexport const MINUTE_OPTIONS = Array.from({ length: 60 }, (_, index) =>\n String(index).padStart(2, '0')\n);\n\nexport const parseTime = (value: string): ParsedTime | undefined => {\n const match = value.match(/^(\\d{2}):(\\d{2})$/);\n if (!match) return undefined;\n\n const hours = Number(match[1]);\n const minutes = Number(match[2]);\n\n if (\n Number.isNaN(hours) ||\n Number.isNaN(minutes) ||\n hours < 0 ||\n hours > 23 ||\n minutes < 0 ||\n minutes > 59\n ) {\n return undefined;\n }\n\n return { hours, minutes };\n};\n\nexport const sanitizeTimeInput = (value: string) => {\n const [hoursRaw = '', minutesRaw = ''] = value.split(':');\n const hasColon = value.includes(':');\n\n let hours = hoursRaw;\n let minutes = minutesRaw;\n\n if (hours.length === 2) {\n const parsedHours = Number(hours);\n if (!Number.isNaN(parsedHours) && parsedHours > 23) {\n hours = '23';\n }\n }\n\n if (minutes.length === 2) {\n const parsedMinutes = Number(minutes);\n if (!Number.isNaN(parsedMinutes) && parsedMinutes > 59) {\n minutes = '59';\n }\n }\n\n if (!hasColon) return hours;\n return `${hours}:${minutes}`;\n};\n\nexport const normalizeDateValue = (value: unknown): Date | undefined => {\n if (!value) return undefined;\n\n if (value instanceof Date) {\n return isValid(value) ? value : undefined;\n }\n\n if (typeof value === 'string') {\n const parsedLocalDateTimeWithSeconds = parse(\n value,\n 'yyyy-MM-dd HH:mm:ss',\n new Date()\n );\n if (isValid(parsedLocalDateTimeWithSeconds)) {\n return parsedLocalDateTimeWithSeconds;\n }\n\n const parsedLocalDateTime = parse(value, 'yyyy-MM-dd HH:mm', new Date());\n if (isValid(parsedLocalDateTime)) {\n return parsedLocalDateTime;\n }\n\n const parsedIso = parseISO(value);\n if (isValid(parsedIso)) return parsedIso;\n\n const parsedDateOnly = parse(value, 'yyyy-MM-dd', new Date());\n if (isValid(parsedDateOnly)) return parsedDateOnly;\n\n const parsedAsDate = new Date(value);\n if (isValid(parsedAsDate)) return parsedAsDate;\n }\n\n return undefined;\n};\n\nexport const formatTimeValue = (hours: number, minutes: number) => {\n return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`;\n};\n\nexport const formatDateTimeAsTime = (date: Date) => {\n return formatTimeValue(date.getHours(), date.getMinutes());\n};\n\nexport const formatDateTimeAsLocalString = (date: Date) => {\n return format(date, 'yyyy-MM-dd HH:mm:ss');\n};\n\nexport const getFallbackTime = (fallbackDate?: Date): ParsedTime => {\n if (fallbackDate) {\n return {\n hours: fallbackDate.getHours(),\n minutes: fallbackDate.getMinutes(),\n };\n }\n\n const now = new Date();\n return {\n hours: now.getHours(),\n minutes: now.getMinutes(),\n };\n};\n\nexport const mergeDateAndTime = (\n selectedDate: Date,\n timeValue: string,\n fallbackDate?: Date\n) => {\n const mergedDate = new Date(selectedDate);\n const parsedTime = parseTime(timeValue) ?? getFallbackTime(fallbackDate);\n\n mergedDate.setHours(parsedTime.hours, parsedTime.minutes, 0, 0);\n return mergedDate;\n};\n"],"mappings":";;;AAOA,MAAa,eAAe,MAAM,KAAK,EAAE,QAAQ,IAAI,GAAG,GAAG,UACzD,OAAO,MAAM,CAAC,SAAS,GAAG,IAAI,CAC/B;AAED,MAAa,iBAAiB,MAAM,KAAK,EAAE,QAAQ,IAAI,GAAG,GAAG,UAC3D,OAAO,MAAM,CAAC,SAAS,GAAG,IAAI,CAC/B;AAED,MAAa,aAAa,UAA0C;CAClE,MAAM,QAAQ,MAAM,MAAM,oBAAoB;AAC9C,KAAI,CAAC,MAAO,QAAO;CAEnB,MAAM,QAAQ,OAAO,MAAM,GAAG;CAC9B,MAAM,UAAU,OAAO,MAAM,GAAG;AAEhC,KACE,OAAO,MAAM,MAAM,IACnB,OAAO,MAAM,QAAQ,IACrB,QAAQ,KACR,QAAQ,MACR,UAAU,KACV,UAAU,GAEV;AAGF,QAAO;EAAE;EAAO;EAAS;;AAG3B,MAAa,qBAAqB,UAAkB;CAClD,MAAM,CAAC,WAAW,IAAI,aAAa,MAAM,MAAM,MAAM,IAAI;CACzD,MAAM,WAAW,MAAM,SAAS,IAAI;CAEpC,IAAI,QAAQ;CACZ,IAAI,UAAU;AAEd,KAAI,MAAM,WAAW,GAAG;EACtB,MAAM,cAAc,OAAO,MAAM;AACjC,MAAI,CAAC,OAAO,MAAM,YAAY,IAAI,cAAc,GAC9C,SAAQ;;AAIZ,KAAI,QAAQ,WAAW,GAAG;EACxB,MAAM,gBAAgB,OAAO,QAAQ;AACrC,MAAI,CAAC,OAAO,MAAM,cAAc,IAAI,gBAAgB,GAClD,WAAU;;AAId,KAAI,CAAC,SAAU,QAAO;AACtB,QAAO,GAAG,MAAM,GAAG;;AAGrB,MAAa,sBAAsB,UAAqC;AACtE,KAAI,CAAC,MAAO,QAAO;AAEnB,KAAI,iBAAiB,KACnB,QAAO,QAAQ,MAAM,GAAG,QAAQ;AAGlC,KAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,iCAAiC,MACrC,OACA,uCACA,IAAI,MAAM,CACX;AACD,MAAI,QAAQ,+BAA+B,CACzC,QAAO;EAGT,MAAM,sBAAsB,MAAM,OAAO,oCAAoB,IAAI,MAAM,CAAC;AACxE,MAAI,QAAQ,oBAAoB,CAC9B,QAAO;EAGT,MAAM,YAAY,SAAS,MAAM;AACjC,MAAI,QAAQ,UAAU,CAAE,QAAO;EAE/B,MAAM,iBAAiB,MAAM,OAAO,8BAAc,IAAI,MAAM,CAAC;AAC7D,MAAI,QAAQ,eAAe,CAAE,QAAO;EAEpC,MAAM,eAAe,IAAI,KAAK,MAAM;AACpC,MAAI,QAAQ,aAAa,CAAE,QAAO;;;AAMtC,MAAa,mBAAmB,OAAe,YAAoB;AACjE,QAAO,GAAG,OAAO,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,OAAO,QAAQ,CAAC,SAAS,GAAG,IAAI;;AAG9E,MAAa,wBAAwB,SAAe;AAClD,QAAO,gBAAgB,KAAK,UAAU,EAAE,KAAK,YAAY,CAAC;;AAG5D,MAAa,+BAA+B,SAAe;AACzD,QAAO,OAAO,MAAM,sBAAsB;;AAG5C,MAAa,mBAAmB,iBAAoC;AAClE,KAAI,aACF,QAAO;EACL,OAAO,aAAa,UAAU;EAC9B,SAAS,aAAa,YAAY;EACnC;CAGH,MAAM,sBAAM,IAAI,MAAM;AACtB,QAAO;EACL,OAAO,IAAI,UAAU;EACrB,SAAS,IAAI,YAAY;EAC1B;;AAGH,MAAa,oBACX,cACA,WACA,iBACG;CACH,MAAM,aAAa,IAAI,KAAK,aAAa;CACzC,MAAM,aAAa,UAAU,UAAU,IAAI,gBAAgB,aAAa;AAExE,YAAW,SAAS,WAAW,OAAO,WAAW,SAAS,GAAG,EAAE;AAC/D,QAAO"}
@@ -0,0 +1,59 @@
1
+ import { cn } from "../src/lib/utils.js";
2
+ import { useEffect, useMemo } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ import { WheelGesturesPlugin } from "embla-carousel-wheel-gestures";
5
+ import useEmblaCarousel from "embla-carousel-react";
6
+
7
+ //#region src/components/date-hour-field/time-wheel-column.tsx
8
+ function TimeWheelColumn({ isOpen, label, options, selectedValue, onSelect }) {
9
+ const [emblaRef, emblaApi] = useEmblaCarousel({
10
+ axis: "y",
11
+ align: "center",
12
+ containScroll: "keepSnaps",
13
+ dragFree: true
14
+ }, useMemo(() => [WheelGesturesPlugin()], []));
15
+ useEffect(() => {
16
+ if (!emblaApi || !isOpen) return;
17
+ emblaApi.reInit();
18
+ if (selectedValue === void 0) {
19
+ emblaApi.scrollTo(0, true);
20
+ return;
21
+ }
22
+ emblaApi.scrollTo(selectedValue, true);
23
+ }, [
24
+ emblaApi,
25
+ isOpen,
26
+ selectedValue
27
+ ]);
28
+ return /* @__PURE__ */ jsxs("div", {
29
+ className: "relative w-16",
30
+ children: [
31
+ /* @__PURE__ */ jsx("p", {
32
+ className: "text-muted-foreground mb-2 text-[11px] font-semibold tracking-[0.12em] uppercase",
33
+ children: label
34
+ }),
35
+ /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 top-6 z-20 h-12 bg-linear-to-b from-popover to-transparent" }),
36
+ /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 z-20 h-12 bg-linear-to-t from-popover to-transparent" }),
37
+ /* @__PURE__ */ jsx("div", {
38
+ className: "h-48 overflow-hidden",
39
+ ref: emblaRef,
40
+ children: /* @__PURE__ */ jsx("div", {
41
+ className: "flex h-full flex-col gap-1 py-4",
42
+ children: options.map((optionLabel) => /* @__PURE__ */ jsx("div", {
43
+ className: "shrink-0 basis-8 ",
44
+ children: /* @__PURE__ */ jsx("button", {
45
+ className: cn("h-full w-full rounded-md text-xs font-medium transition-colors", selectedValue === Number(optionLabel) ? "border-primary bg-primary text-primary-foreground" : "border-border bg-background hover:bg-accent hover:text-accent-foreground"),
46
+ onClick: () => onSelect(optionLabel),
47
+ type: "button",
48
+ children: optionLabel
49
+ })
50
+ }, optionLabel))
51
+ })
52
+ })
53
+ ]
54
+ });
55
+ }
56
+
57
+ //#endregion
58
+ export { TimeWheelColumn };
59
+ //# sourceMappingURL=time-wheel-column.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time-wheel-column.js","names":[],"sources":["../../src/components/date-hour-field/time-wheel-column.tsx"],"sourcesContent":["import { WheelGesturesPlugin } from 'embla-carousel-wheel-gestures';\nimport useEmblaCarousel from 'embla-carousel-react';\nimport { useEffect, useMemo } from 'react';\n\nimport { cn } from '@/lib/utils';\n\ntype TimeWheelColumnProps = {\n isOpen: boolean;\n label: string;\n options: string[];\n selectedValue?: number;\n onSelect: (value: string) => void;\n};\n\nfunction TimeWheelColumn({\n isOpen,\n label,\n options,\n selectedValue,\n onSelect,\n}: TimeWheelColumnProps) {\n const plugins = useMemo(() => [WheelGesturesPlugin()], []);\n const [emblaRef, emblaApi] = useEmblaCarousel(\n {\n axis: 'y',\n align: 'center',\n containScroll: 'keepSnaps',\n dragFree: true,\n },\n plugins\n );\n\n useEffect(() => {\n if (!emblaApi || !isOpen) return;\n\n emblaApi.reInit();\n\n if (selectedValue === undefined) {\n emblaApi.scrollTo(0, true);\n return;\n }\n\n emblaApi.scrollTo(selectedValue, true);\n }, [emblaApi, isOpen, selectedValue]);\n\n return (\n <div className=\"relative w-16\">\n <p className=\"text-muted-foreground mb-2 text-[11px] font-semibold tracking-[0.12em] uppercase\">\n {label}\n </p>\n\n <div className=\"pointer-events-none absolute inset-x-0 top-6 z-20 h-12 bg-linear-to-b from-popover to-transparent\" />\n <div className=\"pointer-events-none absolute inset-x-0 bottom-0 z-20 h-12 bg-linear-to-t from-popover to-transparent\" />\n\n <div className=\"h-48 overflow-hidden\" ref={emblaRef}>\n <div className=\"flex h-full flex-col gap-1 py-4\">\n {options.map((optionLabel) => (\n <div className=\"shrink-0 basis-8 \" key={optionLabel}>\n <button\n className={cn(\n 'h-full w-full rounded-md text-xs font-medium transition-colors',\n selectedValue === Number(optionLabel)\n ? 'border-primary bg-primary text-primary-foreground'\n : 'border-border bg-background hover:bg-accent hover:text-accent-foreground'\n )}\n onClick={() => onSelect(optionLabel)}\n type=\"button\"\n >\n {optionLabel}\n </button>\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n}\n\nexport { TimeWheelColumn };\n"],"mappings":";;;;;;;AAcA,SAAS,gBAAgB,EACvB,QACA,OACA,SACA,eACA,YACuB;CAEvB,MAAM,CAAC,UAAU,YAAY,iBAC3B;EACE,MAAM;EACN,OAAO;EACP,eAAe;EACf,UAAU;EACX,EAPa,cAAc,CAAC,qBAAqB,CAAC,EAAE,EAAE,CAAC,CASzD;AAED,iBAAgB;AACd,MAAI,CAAC,YAAY,CAAC,OAAQ;AAE1B,WAAS,QAAQ;AAEjB,MAAI,kBAAkB,QAAW;AAC/B,YAAS,SAAS,GAAG,KAAK;AAC1B;;AAGF,WAAS,SAAS,eAAe,KAAK;IACrC;EAAC;EAAU;EAAQ;EAAc,CAAC;AAErC,QACE,qBAAC;EAAI,WAAU;;GACb,oBAAC;IAAE,WAAU;cACV;KACC;GAEJ,oBAAC,SAAI,WAAU,sGAAsG;GACrH,oBAAC,SAAI,WAAU,yGAAyG;GAExH,oBAAC;IAAI,WAAU;IAAuB,KAAK;cACzC,oBAAC;KAAI,WAAU;eACZ,QAAQ,KAAK,gBACZ,oBAAC;MAAI,WAAU;gBACb,oBAAC;OACC,WAAW,GACT,mEACA,kBAAkB,OAAO,YAAY,GACjC,sDACA,2EACL;OACD,eAAe,SAAS,YAAY;OACpC,MAAK;iBAEJ;QACM;QAZ6B,YAalC,CACN;MACE;KACF;;GACF"}
@@ -1,35 +1,2 @@
1
- import { FieldPath, FieldValues, UseControllerProps } from "react-hook-form";
2
- import * as react_jsx_runtime1 from "react/jsx-runtime";
3
- import { Matcher } from "react-day-picker";
4
-
5
- //#region src/components/date-hour-field/DateHourField.d.ts
6
- interface DateHourFieldProps<TFieldValues extends FieldValues = FieldValues, TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> extends Omit<UseControllerProps<TFieldValues, TFieldName>, 'disabled'> {
7
- label: string;
8
- description?: string;
9
- className?: string;
10
- disabled?: Matcher | Matcher[] | undefined;
11
- inputDisabled?: boolean;
12
- initialValue?: Date;
13
- endMonth?: Date;
14
- required?: boolean;
15
- help?: string;
16
- hourPlaceholder?: string;
17
- valueType?: 'date' | 'local-string';
18
- }
19
- declare function DateHourField<TFieldValues extends FieldValues = FieldValues, TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({
20
- name,
21
- label,
22
- description,
23
- inputDisabled,
24
- endMonth,
25
- className,
26
- disabled,
27
- initialValue,
28
- required,
29
- help,
30
- hourPlaceholder,
31
- valueType
32
- }: DateHourFieldProps<TFieldValues, TFieldName>): react_jsx_runtime1.JSX.Element;
33
- //#endregion
34
- export { DateHourField, type DateHourFieldProps };
35
- //# sourceMappingURL=date-hour-field.d.ts.map
1
+ import { DateHourField, DateHourFieldProps } from "./date-hour-field/DateHourField.js";
2
+ export { DateHourField, type DateHourFieldProps };