@xsolla/xui-date-picker 0.117.0 → 0.118.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.
package/web/index.mjs CHANGED
@@ -1,5 +1,14 @@
1
+ // src/index.tsx
2
+ import {
3
+ Calendar as Calendar2,
4
+ DualCalendar,
5
+ CalendarHeader,
6
+ CalendarGrid,
7
+ CalendarChips
8
+ } from "@xsolla/xui-calendar";
9
+
1
10
  // src/DatePicker.tsx
2
- import { forwardRef as forwardRef2, useCallback as useCallback3, useEffect as useEffect2, useRef, useState as useState2 } from "react";
11
+ import { forwardRef, useCallback, useEffect, useRef, useState } from "react";
3
12
 
4
13
  // ../primitives-web/src/Box.tsx
5
14
  import React from "react";
@@ -170,456 +179,13 @@ var Box = React.forwardRef(
170
179
  );
171
180
  Box.displayName = "Box";
172
181
 
173
- // ../primitives-web/src/Text.tsx
174
- import styled2 from "styled-components";
175
- import { jsx as jsx2 } from "react/jsx-runtime";
176
- var StyledText = styled2.span`
177
- color: ${(props) => props.color || "inherit"};
178
- font-size: ${(props) => typeof props.fontSize === "number" ? `${props.fontSize}px` : props.fontSize || "inherit"};
179
- font-weight: ${(props) => props.fontWeight || "normal"};
180
- font-family: ${(props) => props.fontFamily || '"Aktiv Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif'};
181
- line-height: ${(props) => typeof props.lineHeight === "number" ? `${props.lineHeight}px` : props.lineHeight || "inherit"};
182
- white-space: ${(props) => props.whiteSpace || "normal"};
183
- text-align: ${(props) => props.textAlign || "inherit"};
184
- text-decoration: ${(props) => props.textDecoration || "none"};
185
- `;
186
- var Text = ({
187
- style,
188
- className,
189
- id,
190
- role,
191
- numberOfLines: _numberOfLines,
192
- ...props
193
- }) => {
194
- return /* @__PURE__ */ jsx2(
195
- StyledText,
196
- {
197
- ...props,
198
- style,
199
- className,
200
- id,
201
- role
202
- }
203
- );
204
- };
205
-
206
182
  // src/DatePicker.tsx
207
183
  import { Input } from "@xsolla/xui-input";
208
184
  import { isWeb, isNative } from "@xsolla/xui-core";
209
- import { format as format3 } from "date-fns";
210
-
211
- // src/Calendar.tsx
212
- import { forwardRef, useCallback as useCallback2, useEffect, useMemo as useMemo2, useState } from "react";
213
- import { useDesignSystem } from "@xsolla/xui-core";
214
- import {
215
- addDays,
216
- addMonths,
217
- eachDayOfInterval,
218
- endOfDay,
219
- endOfMonth,
220
- endOfWeek,
221
- format as format2,
222
- isAfter,
223
- isBefore,
224
- isSameDay,
225
- isSameMonth,
226
- isToday,
227
- isWithinInterval,
228
- startOfDay,
229
- startOfMonth,
230
- startOfWeek,
231
- subMonths
232
- } from "date-fns";
233
- import * as locales2 from "date-fns/locale";
234
-
235
- // src/CalendarHeader.tsx
236
- import { useCallback, useMemo } from "react";
237
- import { IconButton } from "@xsolla/xui-button";
238
- import { Select } from "@xsolla/xui-select";
239
-
240
- // src/utils.ts
241
- import { format, setMonth } from "date-fns";
242
- import * as locales from "date-fns/locale";
243
- var defaultLocale = "enUS";
244
- function formatDate(date, formatStr, locale = defaultLocale) {
245
- const localeObj = locales[locale] || locales[defaultLocale];
246
- return format(date, formatStr, {
247
- locale: localeObj
248
- });
249
- }
250
- function getMonthInLocale(month, locale = defaultLocale) {
251
- return formatDate(setMonth(/* @__PURE__ */ new Date(), month), "LLLL", locale);
252
- }
253
-
254
- // src/CalendarHeader.tsx
255
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
256
- var ArrowLeft = () => /* @__PURE__ */ jsx3(
257
- "svg",
258
- {
259
- viewBox: "0 0 24 24",
260
- width: 16,
261
- height: 16,
262
- fill: "none",
263
- stroke: "currentColor",
264
- strokeWidth: "2",
265
- strokeLinecap: "round",
266
- strokeLinejoin: "round",
267
- children: /* @__PURE__ */ jsx3("polyline", { points: "15 18 9 12 15 6" })
268
- }
269
- );
270
- var ArrowRight = () => /* @__PURE__ */ jsx3(
271
- "svg",
272
- {
273
- viewBox: "0 0 24 24",
274
- width: 16,
275
- height: 16,
276
- fill: "none",
277
- stroke: "currentColor",
278
- strokeWidth: "2",
279
- strokeLinecap: "round",
280
- strokeLinejoin: "round",
281
- children: /* @__PURE__ */ jsx3("polyline", { points: "9 18 15 12 9 6" })
282
- }
283
- );
284
- var months = [
285
- "january",
286
- "february",
287
- "march",
288
- "april",
289
- "may",
290
- "june",
291
- "july",
292
- "august",
293
- "september",
294
- "october",
295
- "november",
296
- "december"
297
- ];
298
- var CalendarHeader = ({
299
- monthDate,
300
- decreaseMonth,
301
- increaseMonth,
302
- changeYear,
303
- changeMonth,
304
- prevMonthButtonDisabled,
305
- nextMonthButtonDisabled,
306
- locale,
307
- minDate,
308
- maxDate
309
- }) => {
310
- const handleChangeMonth = useCallback(
311
- (value) => {
312
- changeMonth(months.indexOf(value));
313
- },
314
- [changeMonth]
315
- );
316
- const handleChangeYear = useCallback(
317
- (value) => {
318
- changeYear(parseInt(value, 10));
319
- },
320
- [changeYear]
321
- );
322
- const monthOptions = useMemo(() => {
323
- return months.map((month, index) => ({
324
- label: getMonthInLocale(index, locale),
325
- value: month
326
- }));
327
- }, [locale]);
328
- const yearOptions = useMemo(() => {
329
- const options = [];
330
- const yearStart = minDate ? minDate.getFullYear() : 1900;
331
- const yearEnd = maxDate ? maxDate.getFullYear() : (/* @__PURE__ */ new Date()).getFullYear() + 100;
332
- for (let i = yearEnd; i >= yearStart; i--) {
333
- options.push({ value: i.toString(), label: i.toString() });
334
- }
335
- return options;
336
- }, [minDate, maxDate]);
337
- return /* @__PURE__ */ jsxs(
338
- Box,
339
- {
340
- width: "100%",
341
- flexDirection: "row",
342
- justifyContent: "space-between",
343
- alignItems: "center",
344
- marginBottom: 16,
345
- gap: 8,
346
- children: [
347
- /* @__PURE__ */ jsx3(
348
- IconButton,
349
- {
350
- size: "xs",
351
- tone: "mono",
352
- variant: "secondary",
353
- onPress: decreaseMonth,
354
- disabled: prevMonthButtonDisabled,
355
- icon: /* @__PURE__ */ jsx3(ArrowLeft, {}),
356
- "aria-label": "Previous month"
357
- }
358
- ),
359
- /* @__PURE__ */ jsxs(Box, { flexDirection: "row", flex: 1, gap: 4, children: [
360
- /* @__PURE__ */ jsx3(Box, { flex: 1.5, children: /* @__PURE__ */ jsx3(
361
- Select,
362
- {
363
- value: months[monthDate.getMonth()],
364
- onValueChange: handleChangeMonth,
365
- options: monthOptions,
366
- size: "sm"
367
- }
368
- ) }),
369
- /* @__PURE__ */ jsx3(Box, { flex: 1, children: /* @__PURE__ */ jsx3(
370
- Select,
371
- {
372
- value: monthDate.getFullYear().toString(),
373
- onValueChange: handleChangeYear,
374
- options: yearOptions,
375
- size: "sm"
376
- }
377
- ) })
378
- ] }),
379
- /* @__PURE__ */ jsx3(
380
- IconButton,
381
- {
382
- size: "xs",
383
- tone: "mono",
384
- variant: "secondary",
385
- onPress: increaseMonth,
386
- disabled: nextMonthButtonDisabled,
387
- icon: /* @__PURE__ */ jsx3(ArrowRight, {}),
388
- "aria-label": "Next month"
389
- }
390
- )
391
- ]
392
- }
393
- );
394
- };
395
-
396
- // src/Calendar.tsx
397
- import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
398
- var Calendar = forwardRef(
399
- ({
400
- locale = "enUS",
401
- onChange,
402
- startDate,
403
- endDate,
404
- selectedDate,
405
- selectsRange = false,
406
- contextMenuMaxHeight,
407
- topContent,
408
- bottomContent,
409
- testID,
410
- minDate,
411
- maxDate,
412
- firstDayOfWeek = 0,
413
- month,
414
- initialMonth
415
- }, ref) => {
416
- const { theme } = useDesignSystem();
417
- const localeObj = locales2[locale] || locales2.enUS;
418
- const [currentMonth, setCurrentMonth] = useState(
419
- month || initialMonth || selectedDate || startDate || /* @__PURE__ */ new Date()
420
- );
421
- const [selectedStartDate, setSelectedStartDate] = useState(startDate);
422
- const [selectedEndDate, setSelectedEndDate] = useState(endDate);
423
- const [locSelectedDate, setLocSelectedDate] = useState(selectedDate);
424
- const [selectingRange, setSelectingRange] = useState(null);
425
- useEffect(() => {
426
- setSelectedStartDate(startDate);
427
- setSelectedEndDate(endDate);
428
- setLocSelectedDate(selectedDate);
429
- if (month !== void 0) {
430
- setCurrentMonth(month);
431
- }
432
- }, [startDate, endDate, selectedDate, month]);
433
- const handleChange = useCallback2(
434
- (date) => {
435
- const newDate = new Date(
436
- currentMonth.getFullYear(),
437
- currentMonth.getMonth(),
438
- date.getDate()
439
- );
440
- if (!selectsRange) {
441
- setLocSelectedDate(newDate);
442
- onChange?.(newDate);
443
- } else {
444
- if (!selectedStartDate || selectedStartDate && selectedEndDate) {
445
- setSelectedStartDate(newDate);
446
- setSelectedEndDate(null);
447
- setSelectingRange(newDate);
448
- onChange?.([newDate, null]);
449
- } else {
450
- const start = selectedStartDate < newDate ? selectedStartDate : newDate;
451
- const end = selectedStartDate < newDate ? newDate : selectedStartDate;
452
- setSelectedStartDate(start);
453
- setSelectedEndDate(end);
454
- setSelectingRange(null);
455
- onChange?.([start, end]);
456
- }
457
- }
458
- },
459
- [onChange, selectsRange, selectedStartDate, selectedEndDate, currentMonth]
460
- );
461
- const decreaseMonth = useCallback2(
462
- () => setCurrentMonth((prev) => subMonths(prev, 1)),
463
- []
464
- );
465
- const increaseMonth = useCallback2(
466
- () => setCurrentMonth((prev) => addMonths(prev, 1)),
467
- []
468
- );
469
- const changeMonth = useCallback2(
470
- (m) => setCurrentMonth((prev) => new Date(prev.getFullYear(), m, 1)),
471
- []
472
- );
473
- const changeYear = useCallback2(
474
- (y) => setCurrentMonth((prev) => new Date(y, prev.getMonth(), 1)),
475
- []
476
- );
477
- const monthStart = startOfMonth(currentMonth);
478
- const monthEnd = endOfMonth(currentMonth);
479
- const weekStartsOn = firstDayOfWeek ?? 0;
480
- const calendarStart = startOfWeek(monthStart, { weekStartsOn });
481
- const calendarEnd = endOfWeek(monthEnd, { weekStartsOn });
482
- const days = eachDayOfInterval({ start: calendarStart, end: calendarEnd });
483
- const weekDays = useMemo2(() => {
484
- return Array.from({ length: 7 }, (_, i) => {
485
- const day = addDays(calendarStart, i);
486
- return format2(day, "EEEEEE", { locale: localeObj });
487
- });
488
- }, [calendarStart, localeObj]);
489
- const weeks = useMemo2(() => {
490
- const weekArray = [];
491
- for (let i = 0; i < days.length; i += 7) {
492
- weekArray.push(days.slice(i, i + 7));
493
- }
494
- return weekArray;
495
- }, [days]);
496
- const isDateDisabled = useCallback2(
497
- (date) => {
498
- if (minDate && isBefore(date, startOfDay(minDate))) return true;
499
- if (maxDate && isAfter(date, endOfDay(maxDate))) return true;
500
- return false;
501
- },
502
- [minDate, maxDate]
503
- );
504
- const isDateInRange = useCallback2(
505
- (date) => {
506
- if (!selectsRange || !selectedStartDate) return false;
507
- const rangeEnd = selectedEndDate || selectingRange;
508
- if (!rangeEnd) return false;
509
- const start = selectedStartDate < rangeEnd ? selectedStartDate : rangeEnd;
510
- const end = selectedStartDate < rangeEnd ? rangeEnd : selectedStartDate;
511
- return isWithinInterval(date, {
512
- start: startOfDay(start),
513
- end: endOfDay(end)
514
- });
515
- },
516
- [selectsRange, selectedStartDate, selectedEndDate, selectingRange]
517
- );
518
- return /* @__PURE__ */ jsxs2(
519
- Box,
520
- {
521
- ref,
522
- testID,
523
- backgroundColor: theme.colors.background.secondary,
524
- borderRadius: 8,
525
- padding: 16,
526
- overflow: "hidden",
527
- style: {
528
- boxShadow: "0px 4px 16px 0px rgba(7, 7, 8, 0.1)",
529
- width: 312
530
- },
531
- children: [
532
- topContent?.({ close: () => {
533
- } }),
534
- /* @__PURE__ */ jsx4(
535
- CalendarHeader,
536
- {
537
- monthDate: currentMonth,
538
- decreaseMonth,
539
- increaseMonth,
540
- changeYear,
541
- changeMonth,
542
- locale,
543
- minDate,
544
- maxDate,
545
- contextMenuMaxHeight
546
- }
547
- ),
548
- /* @__PURE__ */ jsx4(
549
- Box,
550
- {
551
- flexDirection: "row",
552
- justifyContent: "space-between",
553
- marginBottom: 8,
554
- children: weekDays.map((day, i) => /* @__PURE__ */ jsx4(Box, { width: 40, alignItems: "center", children: /* @__PURE__ */ jsx4(
555
- Text,
556
- {
557
- fontSize: 12,
558
- fontWeight: "600",
559
- color: theme.colors.content.tertiary,
560
- children: day.toUpperCase()
561
- }
562
- ) }, i))
563
- }
564
- ),
565
- /* @__PURE__ */ jsx4(Box, { gap: 2, children: weeks.map((week, i) => /* @__PURE__ */ jsx4(Box, { flexDirection: "row", justifyContent: "space-between", children: week.map((day, j) => {
566
- const isOutsideMonth = !isSameMonth(day, currentMonth);
567
- const isSelected = !selectsRange && locSelectedDate && isSameDay(day, locSelectedDate) || selectsRange && selectedStartDate && selectedEndDate && isSameDay(day, selectedStartDate) && isSameDay(day, selectedEndDate);
568
- const isRangeStart = selectsRange && selectedStartDate && isSameDay(day, selectedStartDate);
569
- const isRangeEnd = selectsRange && selectedEndDate && isSameDay(day, selectedEndDate);
570
- const inRange = isDateInRange(day);
571
- const today = isToday(day);
572
- const disabled = isDateDisabled(day);
573
- let bgColor = "transparent";
574
- let textColor = theme.colors.content.primary;
575
- if (isSelected || isRangeStart || isRangeEnd) {
576
- bgColor = theme.colors.background.brand.primary;
577
- textColor = theme.colors.content.on.brand;
578
- } else if (inRange) {
579
- bgColor = theme.colors.overlay.brand;
580
- } else if (today) {
581
- bgColor = theme.colors.overlay.mono;
582
- }
583
- if (isOutsideMonth || disabled) {
584
- textColor = theme.colors.content.tertiary;
585
- }
586
- return /* @__PURE__ */ jsx4(
587
- Box,
588
- {
589
- width: 40,
590
- height: 32,
591
- alignItems: "center",
592
- justifyContent: "center",
593
- borderRadius: isSelected || isRangeStart || isRangeEnd ? 4 : 0,
594
- backgroundColor: bgColor,
595
- cursor: disabled || isOutsideMonth ? "default" : "pointer",
596
- onPress: () => !disabled && !isOutsideMonth && handleChange(day),
597
- hoverStyle: !disabled && !isOutsideMonth && !isSelected ? { backgroundColor: theme.colors.overlay.mono } : void 0,
598
- children: /* @__PURE__ */ jsx4(
599
- Text,
600
- {
601
- color: textColor,
602
- fontSize: 14,
603
- fontWeight: isSelected || isRangeStart || isRangeEnd ? "600" : "400",
604
- children: format2(day, "d")
605
- }
606
- )
607
- },
608
- j
609
- );
610
- }) }, i)) }),
611
- bottomContent?.({ close: () => {
612
- } })
613
- ]
614
- }
615
- );
616
- }
617
- );
618
- Calendar.displayName = "Calendar";
619
-
620
- // src/DatePicker.tsx
621
- import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
622
- var DatePicker = forwardRef2(
185
+ import { format } from "date-fns";
186
+ import { Calendar } from "@xsolla/xui-calendar";
187
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
188
+ var DatePicker = forwardRef(
623
189
  ({
624
190
  onChange,
625
191
  size = "md",
@@ -633,18 +199,18 @@ var DatePicker = forwardRef2(
633
199
  testID,
634
200
  ...rest
635
201
  }) => {
636
- const [open, setOpen] = useState2(false);
637
- const [inputValue, setInputValue] = useState2("");
202
+ const [open, setOpen] = useState(false);
203
+ const [inputValue, setInputValue] = useState("");
638
204
  const containerRef = useRef(null);
639
205
  const formatDateForDisplay = (date) => {
640
206
  if (!date) return "";
641
207
  try {
642
- return format3(date, "MM/dd/yyyy");
208
+ return format(date, "MM/dd/yyyy");
643
209
  } catch {
644
210
  return "";
645
211
  }
646
212
  };
647
- const getDisplayValue = useCallback3(() => {
213
+ const getDisplayValue = useCallback(() => {
648
214
  if (selectsRange) {
649
215
  if (startDate && endDate) {
650
216
  return `${formatDateForDisplay(startDate)} - ${formatDateForDisplay(endDate)}`;
@@ -656,7 +222,7 @@ var DatePicker = forwardRef2(
656
222
  return formatDateForDisplay(selectedDate);
657
223
  }
658
224
  }, [selectsRange, startDate, endDate, selectedDate]);
659
- useEffect2(() => {
225
+ useEffect(() => {
660
226
  setInputValue(getDisplayValue());
661
227
  }, [getDisplayValue]);
662
228
  const handleInputChange = (text) => {
@@ -674,7 +240,7 @@ var DatePicker = forwardRef2(
674
240
  }
675
241
  }
676
242
  };
677
- useEffect2(() => {
243
+ useEffect(() => {
678
244
  if (isNative) return;
679
245
  const handleClickOutside = (event) => {
680
246
  if (containerRef.current && !containerRef.current.contains(event.target)) {
@@ -684,7 +250,7 @@ var DatePicker = forwardRef2(
684
250
  document.addEventListener("mousedown", handleClickOutside);
685
251
  return () => document.removeEventListener("mousedown", handleClickOutside);
686
252
  }, []);
687
- const renderCalendar = () => /* @__PURE__ */ jsx5(
253
+ const renderCalendar = () => /* @__PURE__ */ jsx2(
688
254
  Calendar,
689
255
  {
690
256
  locale,
@@ -696,8 +262,8 @@ var DatePicker = forwardRef2(
696
262
  ...rest
697
263
  }
698
264
  );
699
- return /* @__PURE__ */ jsxs3(Box, { ref: containerRef, position: "relative", width: "100%", children: [
700
- /* @__PURE__ */ jsx5(
265
+ return /* @__PURE__ */ jsxs(Box, { ref: containerRef, position: "relative", width: "100%", children: [
266
+ /* @__PURE__ */ jsx2(
701
267
  Input,
702
268
  {
703
269
  ...rest,
@@ -710,7 +276,7 @@ var DatePicker = forwardRef2(
710
276
  testID
711
277
  }
712
278
  ),
713
- open && (isWeb ? /* @__PURE__ */ jsx5(
279
+ open && (isWeb ? /* @__PURE__ */ jsx2(
714
280
  Box,
715
281
  {
716
282
  position: "absolute",
@@ -724,16 +290,30 @@ var DatePicker = forwardRef2(
724
290
  // Native implementation could use a Modal here
725
291
  // For now, we just show it below the input if needed,
726
292
  // but usually a bottom sheet or centered modal is better.
727
- /* @__PURE__ */ jsx5(Box, { marginTop: 4, children: renderCalendar() })
293
+ /* @__PURE__ */ jsx2(Box, { marginTop: 4, children: renderCalendar() })
728
294
  ))
729
295
  ] });
730
296
  }
731
297
  );
732
298
  DatePicker.displayName = "DatePicker";
299
+
300
+ // src/utils.ts
301
+ import { format as format2 } from "date-fns";
302
+ import * as locales from "date-fns/locale";
303
+ var defaultLocale = "enUS";
304
+ function formatDate(date, formatStr, locale = defaultLocale) {
305
+ const localeObj = locales[locale] || locales[defaultLocale];
306
+ return format2(date, formatStr, {
307
+ locale: localeObj
308
+ });
309
+ }
733
310
  export {
734
- Calendar,
311
+ Calendar2 as Calendar,
312
+ CalendarChips,
313
+ CalendarGrid,
314
+ CalendarHeader,
735
315
  DatePicker,
736
- formatDate,
737
- getMonthInLocale
316
+ DualCalendar,
317
+ formatDate
738
318
  };
739
319
  //# sourceMappingURL=index.mjs.map