@loczer/storefront-sdk 0.194.0 → 0.196.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 (65) hide show
  1. package/dist/chunks/pkg/ui/dist/{Button-CxG2fSpA.js → Button-Cr_u8vnh.js} +1 -1
  2. package/dist/chunks/pkg/ui/dist/{Dialog-4leTWiev.js → Dialog-CczmPDwY.js} +1 -1
  3. package/dist/chunks/pkg/ui/dist/Drawer/{index-DA5V7R_q.js → index-CSvSVP_J.js} +1 -1
  4. package/dist/chunks/pkg/ui/dist/Map/{MapContent-BmKjdWmq.js → MapContent-CDeWtwKa.js} +1 -1
  5. package/dist/chunks/pkg/ui/dist/{Map-CsOTdTtL.js → Map-Cs7wgtH9.js} +2 -2
  6. package/dist/chunks/pkg/ui/dist/{MorphingModalWizard-CfEqkJ0y.js → MorphingModalWizard-j1CgFGLe.js} +4 -3
  7. package/dist/chunks/pkg/ui/dist/{ResponsiveDialog-C6IWYoIg.js → ResponsiveDialog-BVwhTZQo.js} +3 -3
  8. package/dist/chunks/pkg/ui/dist/{ScrollArea-Bjwo84cv.js → ScrollArea-BqLd0xZj.js} +1 -1
  9. package/dist/chunks/pkg/ui/dist/Spinner/{index-DzMEU0iA.js → index-Cgi70z_E.js} +1 -1
  10. package/dist/chunks/pkg/ui/dist/lib/utils-DXB19bzk.js +8 -0
  11. package/dist/components/BikeProductCard/index.js +6 -6
  12. package/dist/components/BookingBikeVariantDialog/index.js +7 -7
  13. package/dist/components/BookingFlowSteps/index.js +11 -11
  14. package/dist/components/BookingPeriodSelector/components/BookingEndDateField.js +1 -1
  15. package/dist/components/BookingPeriodSelector/components/BookingEndTimeField.d.ts.map +1 -1
  16. package/dist/components/BookingPeriodSelector/components/BookingEndTimeField.js +16 -15
  17. package/dist/components/BookingPeriodSelector/components/BookingStartDateField.js +1 -1
  18. package/dist/components/BookingPeriodSelector/components/BookingStartTimeField.d.ts.map +1 -1
  19. package/dist/components/BookingPeriodSelector/components/BookingStartTimeField.js +16 -15
  20. package/dist/components/BookingPeriodSelector/components/internal/BookingHourPickerField.d.ts +1 -1
  21. package/dist/components/BookingPeriodSelector/components/internal/BookingHourPickerField.d.ts.map +1 -1
  22. package/dist/components/BookingPeriodSelector/components/internal/BookingHourPickerField.js +20 -23
  23. package/dist/components/BookingPeriodSelector/components/internal/StorefrontHourPickerField.d.ts +39 -0
  24. package/dist/components/BookingPeriodSelector/components/internal/StorefrontHourPickerField.d.ts.map +1 -0
  25. package/dist/components/BookingPeriodSelector/components/internal/StorefrontHourPickerField.js +830 -0
  26. package/dist/components/BookingPeriodSelector/useBookingPeriodController.d.ts +1 -1
  27. package/dist/components/BookingPeriodSelector/useBookingPeriodController.d.ts.map +1 -1
  28. package/dist/components/BookingPeriodSelector/useBookingPeriodController.js +52 -46
  29. package/dist/components/ContactSection/index.js +35 -35
  30. package/dist/components/ContractSaleDocument/DocumentAcceptanceSection.js +4 -4
  31. package/dist/components/ContractSaleDocument/ThumbnailSidebar.js +1 -1
  32. package/dist/components/DeliveryAddressSelector/index.js +5 -5
  33. package/dist/components/Footer/index.js +11 -11
  34. package/dist/components/FulfillmentSection/index.js +9 -9
  35. package/dist/components/Header/index.js +61 -61
  36. package/dist/components/Map/index.js +1 -1
  37. package/dist/components/PoweredByLoczerBadge/index.js +5 -5
  38. package/dist/components/ProductPriceBadge/index.js +73 -73
  39. package/dist/components/StorefrontCancellationPolicyNotice/index.js +6 -6
  40. package/dist/components/StorefrontCartPanel/index.js +8 -8
  41. package/dist/components/StorefrontInsuranceNotice/index.js +6 -6
  42. package/dist/components/StorefrontPopupMessages/index.js +8 -8
  43. package/dist/components/payment/MollieCardFieldsForm.js +1 -1
  44. package/dist/components/payment/StripeCardFieldsForm.js +1 -1
  45. package/dist/index.d.ts +11 -3
  46. package/dist/lib/utils.d.ts +3 -1
  47. package/dist/lib/utils.d.ts.map +1 -1
  48. package/dist/lib/utils.js +9 -5
  49. package/dist/pages/BookingPage.js +8 -8
  50. package/dist/pages/CheckoutPaymentPage.js +1 -1
  51. package/dist/pages/ContractSaleDocumentPage.js +15 -15
  52. package/dist/pages/HomePage.js +19 -19
  53. package/dist/pages/PaymentLinkPage.js +1 -1
  54. package/dist/pages/PaymentLinkSuccessPage.js +1 -1
  55. package/dist/pages/ProductPage.js +143 -143
  56. package/dist/pages/checkout/components/CheckoutCouponCard.js +5 -5
  57. package/dist/pages/checkout/components/CheckoutPaymentSummaryCard.js +1 -1
  58. package/dist/storefront.css +1 -1
  59. package/package.json +5 -1
  60. package/dist/chunks/node_modules/clsx/dist/clsx-CdyIqUTr.js +0 -16
  61. package/dist/chunks/node_modules/tailwind-merge/dist/bundle-mjs-CF4QheV5.js +0 -1608
  62. package/dist/chunks/pkg/ui/dist/lib/utils-BN5KOMSm.js +0 -8
  63. package/dist/components/BookingPeriodSelector/components/internal/ModalHourPickerField.d.ts +0 -22
  64. package/dist/components/BookingPeriodSelector/components/internal/ModalHourPickerField.d.ts.map +0 -1
  65. package/dist/components/BookingPeriodSelector/components/internal/ModalHourPickerField.js +0 -342
@@ -0,0 +1,830 @@
1
+ import { cn as e } from "../../../../lib/utils.js";
2
+ import * as t from "react";
3
+ import { Fragment as n, jsx as r, jsxs as i } from "react/jsx-runtime";
4
+ import { Check as a, ChevronDown as o, ChevronUp as s } from "lucide-react";
5
+ import { createPortal as c } from "react-dom";
6
+ import { IMaskInput as l } from "react-imask";
7
+ import u, { InputMask as d } from "imask";
8
+ //#region src/components/BookingPeriodSelector/components/internal/StorefrontHourPickerField.tsx
9
+ var f = u;
10
+ typeof f.InputMask != "function" && (f.InputMask = d);
11
+ var p = {
12
+ left: 0,
13
+ top: 0,
14
+ width: 0,
15
+ strategy: "fixed"
16
+ };
17
+ function m(e, t, n) {
18
+ let r = e.getBoundingClientRect(), i = t.offsetHeight, a = window.innerWidth ?? 0, o = window.innerHeight ?? 0, s = r.width, c = r.left;
19
+ c + s > a - 8 && (c = Math.max(8, a - s - 8)), c < 8 && (c = 8);
20
+ let l = r.bottom + 8, u = l + i > o - 8, d = r.top - i - 8;
21
+ if (u && d >= 8 && (l = d), l < 8 && (l = 8), l + i > o - 8 && (l = Math.max(8, o - i - 8)), !n) return {
22
+ left: c,
23
+ top: l,
24
+ width: s,
25
+ strategy: "fixed"
26
+ };
27
+ let f = n.getBoundingClientRect();
28
+ return {
29
+ left: c - f.left,
30
+ top: l - f.top,
31
+ width: s,
32
+ strategy: "absolute"
33
+ };
34
+ }
35
+ function h(e) {
36
+ return String(e).padStart(2, "0");
37
+ }
38
+ function g(e) {
39
+ let t = e.trim();
40
+ if (!t) return null;
41
+ let n = /^(\d{1,2}):(\d{2})$/.exec(t);
42
+ if (!n) return null;
43
+ let r = Number(n[1]), i = Number(n[2]);
44
+ return !Number.isFinite(r) || !Number.isFinite(i) || r < 0 || r > 23 || i < 0 || i > 59 ? null : `${h(r)}:${h(i)}`;
45
+ }
46
+ function _(e) {
47
+ let t = g(e);
48
+ if (t) return `parsed:${t}`;
49
+ let n = e.replace(/\D/g, "");
50
+ if (!n) return "empty";
51
+ if (n.length <= 2) return `hour:${Number(n)}`;
52
+ let r = n.slice(-2), i = n.slice(0, -2);
53
+ return `hour-minute:${Number(i)}:${r}`;
54
+ }
55
+ function v(e, t) {
56
+ let n = g(e);
57
+ return n ? b(t.find((e) => e.value === n)) ? {
58
+ parsed: n,
59
+ selectableValue: n
60
+ } : {
61
+ parsed: n,
62
+ selectableValue: null
63
+ } : null;
64
+ }
65
+ function y(e) {
66
+ let t = /^(\d{2}):(\d{2})$/.exec(e);
67
+ if (!t) return null;
68
+ let n = Number(t[1]), r = Number(t[2]);
69
+ return !Number.isFinite(n) || !Number.isFinite(r) ? null : n * 60 + r;
70
+ }
71
+ function b(e) {
72
+ return e ? !e.disabled : !1;
73
+ }
74
+ function x(e, t, n) {
75
+ let r = e ? n.findIndex((t) => t.value === e) : -1;
76
+ r === -1 && (r = t === 1 ? -1 : n.length);
77
+ for (let e = r + t; e >= 0 && e < n.length; e += t) {
78
+ let t = n[e];
79
+ if (b(t)) return t.value;
80
+ }
81
+ return null;
82
+ }
83
+ function S(e, n, r, i) {
84
+ t.useEffect(() => {
85
+ if (!n || !r) return;
86
+ let t = e.current, a = t?.ownerDocument.defaultView?.IntersectionObserver;
87
+ if (!t || !a) return;
88
+ let o = !0, s = new a((e) => {
89
+ if (!o) return;
90
+ let t = e[0];
91
+ t && !t.isIntersecting && i(!1);
92
+ });
93
+ return s.observe(t), () => {
94
+ o = !1, s.disconnect();
95
+ };
96
+ }, [
97
+ r,
98
+ n,
99
+ i,
100
+ e
101
+ ]);
102
+ }
103
+ function C(e, t) {
104
+ let n = null, r = Infinity, i = -Infinity;
105
+ for (let a of t) {
106
+ if (!b(a)) continue;
107
+ let t = y(a.value);
108
+ if (t == null) continue;
109
+ let o = Math.abs(t - e);
110
+ (o < r || o === r && t > i) && (n = a, r = o, i = t);
111
+ }
112
+ return n;
113
+ }
114
+ function w({ direction: n, viewportRef: i, speed: a = 400, className: c }) {
115
+ let [l, u] = t.useState(!0), d = t.useRef(void 0), f = t.useRef(void 0), p = t.useRef(!1), m = t.useCallback(() => {
116
+ let e = i.current;
117
+ if (!e) {
118
+ u(!0);
119
+ return;
120
+ }
121
+ let { scrollTop: t, scrollHeight: r, clientHeight: a } = e, o = t > 2, s = t < r - a - 2;
122
+ if (!(r > a + 2)) {
123
+ u(!0);
124
+ return;
125
+ }
126
+ u(n === "up" ? !o : !s);
127
+ }, [n, i]);
128
+ t.useEffect(() => {
129
+ let e = i.current;
130
+ if (!e) return;
131
+ m();
132
+ let t = () => m(), n = () => m();
133
+ e.addEventListener("scroll", t, { passive: !0 });
134
+ let r = new ResizeObserver(n);
135
+ r.observe(e);
136
+ let a = new MutationObserver(n);
137
+ return a.observe(e, {
138
+ childList: !0,
139
+ subtree: !0
140
+ }), () => {
141
+ e.removeEventListener("scroll", t), r.disconnect(), a.disconnect();
142
+ };
143
+ }, [i, m]);
144
+ let h = t.useCallback(() => {
145
+ d.current &&= (cancelAnimationFrame(d.current), void 0), p.current = !1, f.current = void 0;
146
+ }, []), g = t.useCallback((e) => {
147
+ let t = i.current;
148
+ if (!t || l || !p.current) {
149
+ h();
150
+ return;
151
+ }
152
+ f.current ||= e;
153
+ let r = a * (e - f.current) / 1e3;
154
+ if (r < .1) {
155
+ d.current = requestAnimationFrame(g);
156
+ return;
157
+ }
158
+ let o = t.scrollTop, s = t.scrollHeight - t.clientHeight, c;
159
+ c = n === "up" ? Math.max(0, o - r) : Math.min(s, o + r), t.scrollTo({ top: c }), f.current = e, (n === "up" ? c > 1 : c < s - 1) && Math.abs(c - o) > .01 ? d.current = requestAnimationFrame(g) : (h(), setTimeout(m, 16));
160
+ }, [
161
+ m,
162
+ n,
163
+ l,
164
+ a,
165
+ h,
166
+ i
167
+ ]), _ = t.useCallback(() => {
168
+ l || !i.current || p.current || (p.current = !0, f.current = void 0, d.current = requestAnimationFrame(g));
169
+ }, [
170
+ l,
171
+ g,
172
+ i
173
+ ]);
174
+ return t.useEffect(() => h, [h]), /* @__PURE__ */ r("div", {
175
+ className: e("flex items-center justify-center py-1 select-none", l ? "cursor-default opacity-40" : "cursor-pointer opacity-100 hover:bg-accent/20", c),
176
+ onPointerEnter: () => {
177
+ l || _();
178
+ },
179
+ onPointerMove: () => {
180
+ !l && !p.current && _();
181
+ },
182
+ onPointerLeave: () => {
183
+ h();
184
+ },
185
+ children: r(n === "up" ? s : o, {
186
+ "aria-hidden": !0,
187
+ className: "h-4 w-4 opacity-50"
188
+ })
189
+ });
190
+ }
191
+ function T({ id: o, value: s, onChange: l, onValueUpdate: u, options: d, placeholder: f = "Select time", className: h, inputClassName: g, disabled: _, readOnly: v, open: y, onOpenChange: x, triggerTestId: C, contentTestId: T, isHydrated: E, portalContainer: D }) {
192
+ let k = t.useId(), A = o ?? `hours-picker-${k}`, j = t.useRef(null), M = t.useRef(null), N = t.useCallback((e) => {
193
+ M.current = e;
194
+ }, []), P = t.useRef(null), F = t.useRef(!1), [I, L] = t.useState(null), R = t.useRef(null), z = t.useRef(null), B = t.useRef(null), [V, H] = t.useState(p), [U, W] = t.useState(!1), G = y ?? U, K = x ?? W, q = t.useRef(!1);
195
+ q.current = G, t.useEffect(() => {
196
+ if (!G || _ || v) return;
197
+ let e = j.current;
198
+ e instanceof HTMLInputElement && (typeof document < "u" && document.activeElement === e || e.focus({ preventScroll: !0 }));
199
+ }, [
200
+ _,
201
+ G,
202
+ v
203
+ ]);
204
+ let J = t.useCallback((e) => {
205
+ P.current = e, L(e);
206
+ }, []), Y = t.useCallback(() => {
207
+ F.current = !0;
208
+ }, []);
209
+ t.useEffect(() => {
210
+ if (!G) return;
211
+ let e = d.find((e) => e.value === s);
212
+ if (e && b(e)) {
213
+ J(e.value);
214
+ return;
215
+ }
216
+ let t = d.find((e) => b(e));
217
+ J(t?.value ?? null);
218
+ }, [
219
+ G,
220
+ d,
221
+ J,
222
+ s
223
+ ]);
224
+ let X = t.useCallback((e) => {
225
+ if (e === null) {
226
+ u && u(null);
227
+ return;
228
+ }
229
+ b(d.find((t) => t.value === e)) && u && u(e);
230
+ }, [u, d]), Z = t.useCallback((e) => {
231
+ if (e === null) {
232
+ u && u(null), l(null);
233
+ return;
234
+ }
235
+ b(d.find((t) => t.value === e)) && (u && u(e), l(e));
236
+ }, [
237
+ l,
238
+ u,
239
+ d
240
+ ]);
241
+ t.useEffect(() => {
242
+ if (!G) return;
243
+ let e = R.current?.ownerDocument ?? document, t = e.defaultView ?? window, n = (e) => {
244
+ let t = e.target;
245
+ if (!(t instanceof Node)) return;
246
+ let n = R.current;
247
+ n && (n.contains(t) || z.current?.contains(t) || K(!1));
248
+ }, r = (e) => {
249
+ if (e.key !== "Escape" || !q.current) return;
250
+ let t = e.target;
251
+ if (!(t instanceof Node)) return;
252
+ let n = R.current, r = z.current;
253
+ !n?.contains(t) && !r?.contains(t) || (e.preventDefault(), e.stopPropagation(), K(!1));
254
+ };
255
+ return e.addEventListener("pointerdown", n, !0), t.addEventListener("keydown", r, !0), () => {
256
+ e.removeEventListener("pointerdown", n, !0), t.removeEventListener("keydown", r, !0);
257
+ };
258
+ }, [G, K]), t.useEffect(() => {
259
+ if (!G) return;
260
+ let e = z.current;
261
+ if (!e) return;
262
+ let t = (e) => {
263
+ let t = B.current;
264
+ if (!t) return;
265
+ let n = e.deltaY;
266
+ if (n === 0) return;
267
+ let r = Math.max(0, t.scrollHeight - t.clientHeight), i = t.scrollTop <= 0, a = t.scrollTop >= r, o = e.target;
268
+ if (o instanceof Node && t.contains(o)) {
269
+ (n < 0 && i || n > 0 && a) && e.preventDefault();
270
+ return;
271
+ }
272
+ e.preventDefault(), t.scrollTop = Math.min(r, Math.max(0, t.scrollTop + n));
273
+ };
274
+ return e.addEventListener("wheel", t, { passive: !1 }), () => {
275
+ e.removeEventListener("wheel", t);
276
+ };
277
+ }, [G]), S(j, G, y === void 0 || x !== void 0, K);
278
+ let Q = t.useCallback(() => {
279
+ if (typeof window > "u") return;
280
+ let e = j.current, t = z.current;
281
+ !(e instanceof HTMLElement) || !t || H(m(e, t, D));
282
+ }, [D]);
283
+ t.useLayoutEffect(() => {
284
+ if (!G || _ || typeof window > "u") return;
285
+ Q();
286
+ let e = window.requestAnimationFrame(Q);
287
+ return window.addEventListener("scroll", Q, !0), window.addEventListener("resize", Q), () => {
288
+ window.cancelAnimationFrame(e), window.removeEventListener("scroll", Q, !0), window.removeEventListener("resize", Q);
289
+ };
290
+ }, [
291
+ _,
292
+ G,
293
+ Q
294
+ ]), t.useEffect(() => {
295
+ if (!G) return;
296
+ let e = B.current;
297
+ if (!e) return;
298
+ let t = requestAnimationFrame(() => {
299
+ let t = e.querySelector("[role=\"option\"][data-state=\"checked\"]");
300
+ if (t instanceof HTMLElement) {
301
+ let n = t.offsetTop - 8, r = t.offsetTop + t.offsetHeight + 8;
302
+ if (n < e.scrollTop) {
303
+ e.scrollTop = Math.max(0, n);
304
+ return;
305
+ }
306
+ r > e.scrollTop + e.clientHeight && (e.scrollTop = Math.max(0, r - e.clientHeight));
307
+ return;
308
+ }
309
+ let n = Array.from(e.querySelectorAll("[role=\"option\"]"));
310
+ if (!n.length) return;
311
+ let r, i;
312
+ for (let e of n) {
313
+ if (!e.hasAttribute("data-disabled")) {
314
+ r = e;
315
+ break;
316
+ }
317
+ i = e;
318
+ }
319
+ if (!r) return;
320
+ let a = Math.max(0, (i || r).offsetTop - 8);
321
+ e.scrollTop = a;
322
+ });
323
+ return () => cancelAnimationFrame(t);
324
+ }, [G, d]), t.useEffect(() => {
325
+ if (!G || !I || !F.current) return;
326
+ let e = B.current;
327
+ if (!e) return;
328
+ let t = e.querySelector(`[role="option"][data-value="${I}"]`);
329
+ if (!(t instanceof HTMLElement)) return;
330
+ let n = t.offsetTop - 8, r = t.offsetTop + t.offsetHeight + 8;
331
+ if (n < e.scrollTop) {
332
+ e.scrollTop = Math.max(0, n);
333
+ return;
334
+ }
335
+ r > e.scrollTop + e.clientHeight && (e.scrollTop = Math.max(0, r - e.clientHeight));
336
+ }, [I, G]);
337
+ let $ = d.find((e) => e.value === s);
338
+ return /* @__PURE__ */ r("div", {
339
+ "data-slot": "hours-picker-input",
340
+ className: e("w-[150px]", h),
341
+ ref: R,
342
+ children: /* @__PURE__ */ i("div", {
343
+ className: "relative",
344
+ children: [/* @__PURE__ */ r(O, {
345
+ id: A,
346
+ placeholder: f,
347
+ value: s,
348
+ onValueUpdate: X,
349
+ onCommit: Z,
350
+ options: d,
351
+ selectedLabel: $?.selectedLabel,
352
+ disabled: _,
353
+ readOnly: v,
354
+ open: G,
355
+ setOpen: K,
356
+ inputClassName: g,
357
+ triggerTestId: C,
358
+ isHydrated: E,
359
+ highlightedValueRef: P,
360
+ setHighlightedValue: J,
361
+ markKeyboardNavigation: Y,
362
+ inputRef: (e) => {
363
+ j.current = e;
364
+ },
365
+ onDraftValueHandlerChange: N
366
+ }), G ? (() => {
367
+ let t = /* @__PURE__ */ r(n, { children: /* @__PURE__ */ i("div", {
368
+ ref: z,
369
+ "data-testid": T,
370
+ "data-state": "open",
371
+ className: e("pointer-events-auto z-[60] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md", "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95"),
372
+ style: {
373
+ position: V.strategy,
374
+ left: V.left,
375
+ top: V.top,
376
+ width: V.width
377
+ },
378
+ children: [
379
+ /* @__PURE__ */ r(w, {
380
+ direction: "up",
381
+ viewportRef: B
382
+ }),
383
+ /* @__PURE__ */ r("div", {
384
+ ref: B,
385
+ role: "listbox",
386
+ className: "max-h-64 overflow-y-auto p-1 [overscroll-behavior:contain] [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden",
387
+ children: d.map((t) => {
388
+ let n = t.value === s;
389
+ return /* @__PURE__ */ i("div", {
390
+ role: "option",
391
+ "aria-selected": n,
392
+ "data-value": t.value,
393
+ "data-state": n ? "checked" : "unchecked",
394
+ "data-disabled": t.disabled ? "" : void 0,
395
+ className: e("relative flex w-full select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none cursor-pointer", t.disabled && "pointer-events-none opacity-50", I === t.value && "bg-accent text-accent-foreground"),
396
+ onMouseDown: (e) => {
397
+ e.preventDefault();
398
+ },
399
+ onClick: () => {
400
+ t.disabled || (M.current?.(t.value), J(t.value), j.current?.focus({ preventScroll: !0 }), Z(t.value), K(!1));
401
+ },
402
+ onPointerEnter: () => {
403
+ F.current || (F.current = !1, J(t.value));
404
+ },
405
+ onPointerMove: (e) => {
406
+ F.current && e.movementX === 0 && e.movementY === 0 || (F.current = !1, J(t.value));
407
+ },
408
+ children: [/* @__PURE__ */ r("span", {
409
+ className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center",
410
+ children: n ? /* @__PURE__ */ r(a, {
411
+ "aria-hidden": !0,
412
+ className: "h-4 w-4"
413
+ }) : null
414
+ }), /* @__PURE__ */ i("div", {
415
+ className: "flex flex-col",
416
+ children: [/* @__PURE__ */ r("span", { children: t.label }), t.description == null ? null : /* @__PURE__ */ r("span", {
417
+ "data-slot": "description",
418
+ className: "text-xs text-muted-foreground",
419
+ children: t.description
420
+ })]
421
+ })]
422
+ }, t.value);
423
+ })
424
+ }),
425
+ /* @__PURE__ */ r(w, {
426
+ direction: "down",
427
+ viewportRef: B
428
+ })
429
+ ]
430
+ }) });
431
+ return typeof document > "u" ? t : c(t, D ?? document.body);
432
+ })() : null]
433
+ })
434
+ });
435
+ }
436
+ T.displayName = "HourPickerInput";
437
+ function E({ id: s, value: l, onChange: u, onValueUpdate: d, options: f, placeholder: h = "Select time", className: g, inputClassName: _, disabled: v, readOnly: y, open: C, onOpenChange: T, triggerTestId: E, contentTestId: D, isHydrated: O, portalContainer: k }) {
438
+ let A = t.useId(), j = s ?? `hours-picker-${A}`, M = t.useRef(null), N = t.useRef(null), P = t.useRef(null), F = t.useRef(null), [I, L] = t.useState(p), [R, z] = t.useState(null), [B, V] = t.useState(!1), H = C ?? B, U = T ?? V, W = t.useRef(!1);
439
+ W.current = H;
440
+ let G = t.useCallback((e) => {
441
+ b(f.find((t) => t.value === e)) && (d && d(e), u(e));
442
+ }, [
443
+ u,
444
+ d,
445
+ f
446
+ ]);
447
+ t.useEffect(() => {
448
+ if (!H) return;
449
+ let e = f.find((e) => e.value === l);
450
+ if (b(e)) {
451
+ z(e.value);
452
+ return;
453
+ }
454
+ let t = f.find((e) => b(e));
455
+ z(t?.value ?? null);
456
+ }, [
457
+ f,
458
+ H,
459
+ l
460
+ ]), t.useEffect(() => {
461
+ if (!H || !R) return;
462
+ let e = F.current;
463
+ if (!e) return;
464
+ let t = e.querySelector(`[role="option"][data-value="${R}"]`);
465
+ if (!(t instanceof HTMLElement)) return;
466
+ let n = t.offsetTop - 8, r = t.offsetTop + t.offsetHeight + 8;
467
+ if (n < e.scrollTop) {
468
+ e.scrollTop = Math.max(0, n);
469
+ return;
470
+ }
471
+ r > e.scrollTop + e.clientHeight && (e.scrollTop = Math.max(0, r - e.clientHeight));
472
+ }, [R, H]), S(M, H, C === void 0 || T !== void 0, U);
473
+ let K = t.useCallback(() => {
474
+ if (typeof window > "u") return;
475
+ let e = M.current, t = P.current;
476
+ !(e instanceof HTMLElement) || !t || L(m(e, t, k));
477
+ }, [k]);
478
+ t.useLayoutEffect(() => {
479
+ if (!H || v || typeof window > "u") return;
480
+ K();
481
+ let e = window.requestAnimationFrame(K);
482
+ return window.addEventListener("scroll", K, !0), window.addEventListener("resize", K), () => {
483
+ window.cancelAnimationFrame(e), window.removeEventListener("scroll", K, !0), window.removeEventListener("resize", K);
484
+ };
485
+ }, [
486
+ v,
487
+ H,
488
+ K
489
+ ]), t.useEffect(() => {
490
+ if (!H) return;
491
+ let e = N.current?.ownerDocument ?? document, t = e.defaultView ?? window, n = (e) => {
492
+ let t = e.target;
493
+ t instanceof Node && (N.current?.contains(t) || P.current?.contains(t) || U(!1));
494
+ }, r = (e) => {
495
+ if (e.key !== "Escape" || !W.current) return;
496
+ let t = e.target;
497
+ if (!(t instanceof Node)) return;
498
+ let n = N.current, r = P.current;
499
+ !n?.contains(t) && !r?.contains(t) || (e.preventDefault(), e.stopPropagation(), U(!1), M.current?.focus({ preventScroll: !0 }));
500
+ };
501
+ return e.addEventListener("pointerdown", n, !0), t.addEventListener("keydown", r, !0), () => {
502
+ e.removeEventListener("pointerdown", n, !0), t.removeEventListener("keydown", r, !0);
503
+ };
504
+ }, [H, U]);
505
+ let q = f.find((e) => e.value === l), J = q?.compactSelectedLabel ?? q?.selectedLabel ?? q?.label ?? l, Y = f.findIndex((e) => e.value === R), X = Y >= 0 ? `${j}-option-${Y}` : void 0;
506
+ return /* @__PURE__ */ i("div", {
507
+ "data-slot": "hours-picker-field",
508
+ className: e("w-[150px]", g),
509
+ ref: N,
510
+ children: [/* @__PURE__ */ i("button", {
511
+ ref: M,
512
+ id: j,
513
+ type: "button",
514
+ role: "combobox",
515
+ "aria-expanded": H,
516
+ "aria-controls": `${j}-content`,
517
+ "aria-haspopup": "listbox",
518
+ "aria-activedescendant": H ? X : void 0,
519
+ disabled: v,
520
+ "data-testid": E,
521
+ "data-hydrated": O ? "true" : void 0,
522
+ className: e("flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", !l && "text-muted-foreground", H && "ring-2 ring-primary ring-offset-2", _),
523
+ onClick: () => {
524
+ v || y || U(!H);
525
+ },
526
+ onKeyDown: (e) => {
527
+ if (v || y) return;
528
+ if (e.key === "Tab") {
529
+ H && U(!1);
530
+ return;
531
+ }
532
+ if (e.key === "ArrowDown" || e.key === "ArrowUp") {
533
+ if (e.preventDefault(), !H) {
534
+ U(!0);
535
+ return;
536
+ }
537
+ let t = x(R ?? l, e.key === "ArrowDown" ? 1 : -1, f);
538
+ if (!t) return;
539
+ z(t), d?.(t);
540
+ return;
541
+ }
542
+ if (e.key !== "Enter" && e.key !== " ") return;
543
+ if (e.preventDefault(), !H) {
544
+ U(!0);
545
+ return;
546
+ }
547
+ let t = f.find((e) => e.value === R), n = b(t) ? t.value : f.find((e) => b(e))?.value;
548
+ n && (G(n), U(!1));
549
+ },
550
+ children: [/* @__PURE__ */ r("span", {
551
+ className: "line-clamp-1 text-left",
552
+ children: l ? J : h
553
+ }), /* @__PURE__ */ r(o, {
554
+ "aria-hidden": !0,
555
+ className: "h-4 w-4 shrink-0 opacity-50"
556
+ })]
557
+ }), H ? (() => {
558
+ let t = /* @__PURE__ */ r(n, { children: /* @__PURE__ */ i("div", {
559
+ ref: P,
560
+ id: `${j}-content`,
561
+ "data-testid": D,
562
+ "data-state": "open",
563
+ className: e("pointer-events-auto z-[60] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md", "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95"),
564
+ style: {
565
+ position: I.strategy,
566
+ left: I.left,
567
+ top: I.top,
568
+ width: I.width
569
+ },
570
+ children: [
571
+ /* @__PURE__ */ r(w, {
572
+ direction: "up",
573
+ viewportRef: F
574
+ }),
575
+ /* @__PURE__ */ r("div", {
576
+ ref: F,
577
+ role: "listbox",
578
+ className: "max-h-64 overflow-y-auto p-1 [overscroll-behavior:contain] [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden",
579
+ children: f.map((t, n) => {
580
+ let o = t.value === l, s = t.value === R;
581
+ return /* @__PURE__ */ i("div", {
582
+ id: `${j}-option-${n}`,
583
+ role: "option",
584
+ "aria-selected": o,
585
+ "aria-disabled": t.disabled || void 0,
586
+ "data-value": t.value,
587
+ "data-state": o ? "checked" : "unchecked",
588
+ "data-disabled": t.disabled ? "" : void 0,
589
+ className: e("relative flex w-full select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none cursor-pointer", t.disabled && "pointer-events-none opacity-50", s && "bg-accent text-accent-foreground"),
590
+ onMouseDown: (e) => {
591
+ e.preventDefault();
592
+ },
593
+ onClick: () => {
594
+ t.disabled || y || (z(t.value), G(t.value), U(!1), M.current?.focus({ preventScroll: !0 }));
595
+ },
596
+ children: [/* @__PURE__ */ r("span", {
597
+ className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center",
598
+ children: o ? /* @__PURE__ */ r(a, {
599
+ "aria-hidden": !0,
600
+ className: "h-4 w-4"
601
+ }) : null
602
+ }), /* @__PURE__ */ i("div", {
603
+ className: "flex flex-col",
604
+ children: [/* @__PURE__ */ r("span", { children: t.label }), t.description == null ? null : /* @__PURE__ */ r("span", {
605
+ "data-slot": "description",
606
+ className: "text-xs text-muted-foreground",
607
+ children: t.description
608
+ })]
609
+ })]
610
+ }, t.value);
611
+ })
612
+ }),
613
+ /* @__PURE__ */ r(w, {
614
+ direction: "down",
615
+ viewportRef: F
616
+ })
617
+ ]
618
+ }) });
619
+ return typeof document > "u" ? t : c(t, k ?? document.body);
620
+ })() : null]
621
+ });
622
+ }
623
+ function D({ compact: e = !1, ...t }) {
624
+ return r(e ? E : T, { ...t });
625
+ }
626
+ D.displayName = "HourPickerField";
627
+ function O({ id: n, placeholder: a, value: s, onValueUpdate: c, onCommit: u, options: d, selectedLabel: f, disabled: p, readOnly: m, open: g, setOpen: x, inputClassName: S, triggerTestId: w, isHydrated: T, highlightedValueRef: E, setHighlightedValue: D, markKeyboardNavigation: O, inputRef: k, onDraftValueHandlerChange: A }) {
628
+ let j = t.useRef(!1), M = t.useRef(!1), N = t.useRef(!1), P = t.useRef(null), F = t.useRef(null), I = t.useRef(!1), [L, R] = t.useState(() => s || ""), [z, B] = t.useState(!1);
629
+ t.useEffect(() => (A((e) => {
630
+ R(e), B(!1);
631
+ }), () => {
632
+ A(null);
633
+ }), [A]);
634
+ let V = t.useCallback((e) => {
635
+ let t = E.current ?? s ?? "", n = d.findIndex((e) => e.value === t);
636
+ n === -1 && (n = e === 1 ? -1 : d.length);
637
+ for (let t = n + e; t >= 0 && t < d.length; t += e) {
638
+ let e = d[t];
639
+ if (b(e)) {
640
+ D(e.value), P.current = e.value, R(e.value), B(!1), c(e.value);
641
+ return;
642
+ }
643
+ }
644
+ }, [
645
+ E,
646
+ c,
647
+ d,
648
+ D,
649
+ s
650
+ ]);
651
+ t.useEffect(() => {
652
+ j.current || (R(s || ""), B(!1));
653
+ }, [s]), t.useEffect(() => {
654
+ F.current = _(L);
655
+ }, [L]), t.useEffect(() => {
656
+ s === null && (I.current = !1);
657
+ }, [s]);
658
+ let H = s != null && f != null && !z, U = e("peer flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 pr-10 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", "transition-[border-color,box-shadow]", !L && "text-muted-foreground", H && "text-transparent", g && "ring-2 ring-primary ring-offset-2", "[&_[data-slot='description']]:hidden", S);
659
+ return /* @__PURE__ */ i("div", {
660
+ className: "relative",
661
+ children: [
662
+ /* @__PURE__ */ r(l, {
663
+ id: n,
664
+ "data-testid": w,
665
+ "data-hydrated": T ? "true" : void 0,
666
+ type: "text",
667
+ disabled: p,
668
+ readOnly: m,
669
+ inputRef: k,
670
+ autoComplete: "off",
671
+ mask: [{
672
+ mask: "00:00",
673
+ lazy: !0
674
+ }, {
675
+ mask: "0:00",
676
+ lazy: !0
677
+ }],
678
+ dispatch: (e, t) => {
679
+ let n = (t.value + e).replace(/\D/g, "");
680
+ if (n.length <= 2 || n.length >= 4) return t.compiledMasks[0];
681
+ let r = h(Number(n.slice(0, 2)));
682
+ return d.some((e) => e.value.startsWith(`${r}:`)) ? t.compiledMasks[0] : t.compiledMasks[1];
683
+ },
684
+ placeholder: a,
685
+ value: L,
686
+ className: U,
687
+ onAccept: (e, t, n) => {
688
+ if (!n) return;
689
+ B(!0);
690
+ let r = typeof e == "string" ? e : String(e ?? ""), i = r.replace(/\D/g, ""), a = _(r);
691
+ if (F.current !== a) {
692
+ if (F.current = a, R(r), i.length !== 0) {
693
+ I.current = !1;
694
+ return;
695
+ }
696
+ s && !I.current && (I.current = !0, u(null));
697
+ }
698
+ },
699
+ onComplete: (e, t, n) => {
700
+ if (!n) return;
701
+ let r = typeof e == "string" ? e : String(e ?? "");
702
+ if (P.current === r) {
703
+ P.current = null;
704
+ return;
705
+ }
706
+ let i = v(r, d);
707
+ if (!i) return;
708
+ if (i.selectableValue) {
709
+ if (D(i.selectableValue), R(i.selectableValue), B(!1), s === i.selectableValue) return;
710
+ u(i.selectableValue);
711
+ return;
712
+ }
713
+ let a = y(i.parsed);
714
+ if (a == null) return;
715
+ let o = C(a, d);
716
+ o && D(o.value);
717
+ },
718
+ onPointerDown: () => {
719
+ M.current = !0, !p && (g || x(!0));
720
+ },
721
+ onMouseDown: (e) => {
722
+ M.current = !0, N.current = typeof document < "u" && document.activeElement === e.currentTarget, !p && (g || x(!0));
723
+ },
724
+ onClick: () => {
725
+ p || g || x(!0);
726
+ },
727
+ onKeyDown: (e) => {
728
+ if (!p) {
729
+ if (e.key === "Tab" && g && !e.defaultPrevented) {
730
+ x(!1);
731
+ return;
732
+ }
733
+ if (e.key === "Escape") {
734
+ if (!g) return;
735
+ e.preventDefault(), x(!1);
736
+ return;
737
+ }
738
+ if (!g && !e.defaultPrevented && (e.key.length === 1 || e.key === "Backspace" || e.key === "Delete") && !e.ctrlKey && !e.metaKey && !e.altKey && x(!0), e.key === "ArrowDown" || e.key === "ArrowUp") {
739
+ if (O(), e.preventDefault(), !g) {
740
+ x(!0);
741
+ return;
742
+ }
743
+ V(e.key === "ArrowDown" ? 1 : -1);
744
+ return;
745
+ }
746
+ if (e.key === "Enter") {
747
+ O();
748
+ let t = v(L, d);
749
+ if (!t) {
750
+ if (!g || L.trim() !== "") return;
751
+ let t = d.find((e) => e.value === E.current), n = (b(t) ? t?.value : void 0) ?? d.find((e) => b(e))?.value;
752
+ if (!n) return;
753
+ e.preventDefault(), D(n), R(n), B(!1), u(n), x(!1);
754
+ return;
755
+ }
756
+ if (t.selectableValue) {
757
+ e.preventDefault(), D(t.selectableValue), R(t.selectableValue), B(!1), u(t.selectableValue), x(!1);
758
+ return;
759
+ }
760
+ let n = y(t.parsed);
761
+ if (n == null) return;
762
+ let r = C(n, d);
763
+ if (!r) return;
764
+ e.preventDefault(), D(r.value), R(r.value), B(!1), u(r.value), x(!1);
765
+ return;
766
+ }
767
+ }
768
+ },
769
+ onFocus: (e) => {
770
+ let t = !M.current || !N.current;
771
+ if (M.current = !1, N.current = !1, j.current = !0, t) {
772
+ let t = e.currentTarget;
773
+ requestAnimationFrame(() => t.select());
774
+ }
775
+ p || g || x(!0);
776
+ },
777
+ onBlur: () => {
778
+ j.current = !1, B(!1);
779
+ let e = L.trim();
780
+ if (!e) {
781
+ R(s || "");
782
+ return;
783
+ }
784
+ let t = v(e, d);
785
+ if (!t) {
786
+ R(s || "");
787
+ return;
788
+ }
789
+ if (!t.selectableValue) {
790
+ R(s || "");
791
+ return;
792
+ }
793
+ R(t.selectableValue), s !== t.selectableValue && u(t.selectableValue);
794
+ }
795
+ }),
796
+ H ? /* @__PURE__ */ r("span", {
797
+ "aria-hidden": "true",
798
+ "data-slot": "hours-picker-input-selected-label",
799
+ className: e("pointer-events-none absolute inset-y-0 left-3 right-10 flex min-w-0 items-center bg-background text-base text-foreground md:text-sm", p && "opacity-50"),
800
+ children: /* @__PURE__ */ r("span", {
801
+ className: "min-w-0 truncate",
802
+ children: f
803
+ })
804
+ }) : null,
805
+ /* @__PURE__ */ r("button", {
806
+ type: "button",
807
+ tabIndex: -1,
808
+ disabled: p,
809
+ "data-slot": "hours-picker-input-toggle",
810
+ className: e("absolute right-1 top-1/2 inline-flex size-8 -translate-y-1/2 items-center justify-center rounded-md text-muted-foreground transition-colors hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"),
811
+ "aria-label": g ? "Close time picker" : "Open time picker",
812
+ onPointerDown: (e) => {
813
+ e.preventDefault();
814
+ },
815
+ onMouseDown: (e) => {
816
+ e.preventDefault();
817
+ },
818
+ onClick: () => {
819
+ p || x(!g);
820
+ },
821
+ children: /* @__PURE__ */ r(o, {
822
+ "aria-hidden": !0,
823
+ className: "size-4"
824
+ })
825
+ })
826
+ ]
827
+ });
828
+ }
829
+ //#endregion
830
+ export { D as HourPickerField, T as HourPickerInput };