@povio/ui 2.2.9-rc.42 → 2.2.9-rc.44

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 (50) hide show
  1. package/dist/components/buttons/Button/Button.d.ts +3 -4
  2. package/dist/components/buttons/Button/Button.js +32 -41
  3. package/dist/components/buttons/PillButton/PillButton.d.ts +2 -2
  4. package/dist/components/buttons/PillButton/PillButton.js +1 -1
  5. package/dist/components/buttons/TextButton/TextButton.d.ts +2 -1
  6. package/dist/components/buttons/ToggleButton/ToggleButton.d.ts +2 -1
  7. package/dist/components/buttons/shared/ButtonContent.d.ts +3 -3
  8. package/dist/components/buttons/shared/ButtonContent.js +2 -2
  9. package/dist/components/inputs/DateTime/DatePicker/DatePicker.d.ts +5 -1
  10. package/dist/components/inputs/DateTime/DatePicker/DatePicker.js +82 -28
  11. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.js +3 -1
  12. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.d.ts +4 -0
  13. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.js +40 -10
  14. package/dist/components/inputs/DateTime/TimePicker/TimePicker.d.ts +1 -0
  15. package/dist/components/inputs/DateTime/TimePicker/TimePicker.js +12 -5
  16. package/dist/components/inputs/DateTime/shared/Calendar.d.ts +6 -1
  17. package/dist/components/inputs/DateTime/shared/Calendar.js +112 -15
  18. package/dist/components/inputs/DateTime/shared/CalendarHeader.d.ts +2 -1
  19. package/dist/components/inputs/DateTime/shared/CalendarHeader.js +28 -4
  20. package/dist/components/inputs/DateTime/shared/DateField.d.ts +5 -1
  21. package/dist/components/inputs/DateTime/shared/DateField.js +60 -13
  22. package/dist/components/inputs/DateTime/shared/DatePickerInput.d.ts +5 -1
  23. package/dist/components/inputs/DateTime/shared/DatePickerInput.js +15 -6
  24. package/dist/components/inputs/DateTime/shared/MonthPicker.d.ts +5 -1
  25. package/dist/components/inputs/DateTime/shared/MonthPicker.js +40 -8
  26. package/dist/components/inputs/DateTime/shared/YearPicker.d.ts +5 -1
  27. package/dist/components/inputs/DateTime/shared/YearPicker.js +42 -8
  28. package/dist/components/inputs/Input/NumberInput/NumberInput.js +2 -0
  29. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.js +2 -0
  30. package/dist/components/inputs/Input/TextInput/TextInput.js +2 -0
  31. package/dist/components/inputs/Inputs/InputItem.d.ts +1 -1
  32. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.js +1 -0
  33. package/dist/components/inputs/Selection/Select/Select.js +1 -0
  34. package/dist/components/inputs/Selection/shared/SelectMobile.js +2 -1
  35. package/dist/components/inputs/Selection/shared/select.context.js +1 -1
  36. package/dist/components/inputs/Skeleton/InputFrame.js +2 -2
  37. package/dist/components/overlays/BottomSheet/BottomSheet.js +2 -3
  38. package/dist/components/overlays/Tooltip/TooltipEllipsis.d.ts +2 -2
  39. package/dist/components/segment/Segment.js +2 -1
  40. package/dist/components/segment/SegmentItem.d.ts +1 -1
  41. package/dist/components/segment/SegmentItem.js +5 -2
  42. package/dist/components/segment/segment.types.d.ts +1 -0
  43. package/dist/config/link.context.js +4 -2
  44. package/dist/config/uiConfig.context.d.ts +1 -1
  45. package/dist/config/uiConfig.context.js +3 -1
  46. package/dist/index.js +1 -1
  47. package/dist/utils/date-time.utils.d.ts +7 -6
  48. package/dist/utils/date-time.utils.js +55 -16
  49. package/package.json +4 -4
  50. package/dist/components/inputs/DateTime/shared/dateSegment.utils.js +0 -9
@@ -2,12 +2,12 @@ import { Typography } from "../../../text/Typography/Typography.js";
2
2
  import { useScrollableListBox } from "../../../../hooks/useScrollableListBox.js";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { clsx } from "clsx";
5
- import { useMemo } from "react";
5
+ import { useMemo, useRef } from "react";
6
6
  import { ListBox, ListBoxItem } from "react-aria-components";
7
7
  import { today } from "@internationalized/date";
8
8
  import { useDateFormatter } from "@react-aria/i18n";
9
9
  //#region src/components/inputs/DateTime/shared/YearPicker.tsx
10
- var YearPicker = ({ state, onSelectionChange }) => {
10
+ var YearPicker = ({ state, onSelectionChange, onDateChange, onCommit, selectedDate }) => {
11
11
  const formatter = useDateFormatter({
12
12
  year: "numeric",
13
13
  timeZone: state.timeZone
@@ -28,20 +28,42 @@ var YearPicker = ({ state, onSelectionChange }) => {
28
28
  if (state.maxValue && year > state.maxValue.year) return true;
29
29
  return false;
30
30
  };
31
- const selectedYear = years.findIndex((year) => year.value === state.focusedDate.year);
31
+ const getSelectedYearIndex = () => {
32
+ if (selectedDate) {
33
+ const selectedIndexFromValue = years.findIndex((year) => year.value === selectedDate.year);
34
+ if (selectedIndexFromValue >= 0) return selectedIndexFromValue;
35
+ }
36
+ const focusedYearIndex = years.findIndex((year) => year.value === state.focusedDate.year);
37
+ if (focusedYearIndex < 0) return null;
38
+ return focusedYearIndex;
39
+ };
40
+ const selectedYearIndex = getSelectedYearIndex();
41
+ const lastPressedYearIndexRef = useRef(null);
42
+ const listBoxSelectionProps = {};
43
+ if (selectedYearIndex !== null) listBoxSelectionProps.selectedKeys = [selectedYearIndex];
44
+ const parseYearIndexFromKey = (key) => {
45
+ if (typeof key === "number") return key;
46
+ if (typeof key === "string") {
47
+ const parsedIndex = Number.parseInt(key, 10);
48
+ if (!Number.isNaN(parsedIndex)) return parsedIndex;
49
+ }
50
+ return null;
51
+ };
32
52
  const { ref } = useScrollableListBox();
33
53
  return /* @__PURE__ */ jsx(ListBox, {
34
54
  ref,
35
55
  autoFocus: true,
36
56
  "aria-label": "Year",
37
57
  selectionMode: "single",
38
- selectedKeys: [selectedYear],
58
+ ...listBoxSelectionProps,
39
59
  onSelectionChange: (key) => {
40
60
  if (key === "all") return;
41
- const index = [...key][0];
42
- if (typeof index === "number") {
43
- const date = state.focusedDate.set({ year: years[index].value });
44
- state.setFocusedDate(date);
61
+ const selectedKey = [...key][0];
62
+ const selectedYearIndexValue = parseYearIndexFromKey(selectedKey);
63
+ if (selectedYearIndexValue !== null && years[selectedYearIndexValue]) {
64
+ const nextSelectedDate = state.focusedDate.set({ year: years[selectedYearIndexValue].value });
65
+ state.setFocusedDate(nextSelectedDate);
66
+ onDateChange?.(nextSelectedDate);
45
67
  }
46
68
  onSelectionChange(key);
47
69
  },
@@ -52,6 +74,18 @@ var YearPicker = ({ state, onSelectionChange }) => {
52
74
  id: index,
53
75
  textValue: year.formatted,
54
76
  isDisabled,
77
+ onPress: () => {
78
+ const isSecondConsecutivePress = lastPressedYearIndexRef.current === index;
79
+ lastPressedYearIndexRef.current = index;
80
+ const nextSelectedDate = state.focusedDate.set({ year: year.value });
81
+ state.setFocusedDate(nextSelectedDate);
82
+ onDateChange?.(nextSelectedDate);
83
+ if (!isSecondConsecutivePress) return;
84
+ if (!selectedDate) return;
85
+ if (selectedYearIndex === null) return;
86
+ if (index !== selectedYearIndex) return;
87
+ onCommit?.();
88
+ },
55
89
  className: clsx("flex px-4 py-2 text-interactive-text-secondary-idle outline-none", "border-elevation-outline-default-1 border-b border-solid bg-elevation-fill-default-1 last:border-b-0", "hover:text-interactive-text-secondary-hover", "selected:bg-interactive-contained-primary-idle selected:text-interactive-text-secondary-idle-inverted", "focus-visible:bg-interactive-contained-primary-focus focus-visible:text-interactive-text-secondary-idle-inverted", isDisabled ? "cursor-default opacity-50" : "cursor-pointer"),
56
90
  children: /* @__PURE__ */ jsx(Typography, {
57
91
  as: "span",
@@ -165,6 +165,8 @@ var NumberInput = ({ renderStaticInput, ...props }) => {
165
165
  renderStatic: true,
166
166
  onStaticInteract: renderRealInput,
167
167
  inputClassName: props.inputClassName,
168
+ contentClassName: "pr-0!",
169
+ trailingClassName: "py-0! pl-0!",
168
170
  wrapContentAndTrailing: true,
169
171
  children: (dataAttributeProps) => /* @__PURE__ */ jsx("input", {
170
172
  type: "text",
@@ -163,6 +163,8 @@ var NumberRangeInput = ({ renderStaticInput, ...props }) => {
163
163
  isDisabled,
164
164
  className: clsx("group w-full", as === "inline" && "h-full", props.className),
165
165
  inputClassName: props.inputClassName,
166
+ contentClassName: "pr-0!",
167
+ trailingClassName: "py-0! pl-0!",
166
168
  contentWrapperClassName: "flex w-full items-center gap-input-gap-input-text-to-elements",
167
169
  dataAttributes,
168
170
  renderStatic: true,
@@ -160,6 +160,8 @@ var TextInput = ({ renderStaticInput, ...props }) => {
160
160
  renderStatic: true,
161
161
  onStaticInteract: renderRealInput,
162
162
  inputClassName: props.inputClassName,
163
+ contentClassName: "pr-0!",
164
+ trailingClassName: "py-0! pl-0!",
163
165
  wrapContentAndTrailing: true,
164
166
  children: (dataAttributeProps) => /* @__PURE__ */ jsx("input", {
165
167
  ref: inputRef,
@@ -18,7 +18,7 @@ declare const componentRegistry: {
18
18
  readonly autocomplete: typeof Autocomplete;
19
19
  readonly queryAutocomplete: <TFieldValues extends import('react-hook-form').FieldValues, TSelectItem extends import('../../..').SelectItem<any>, TQueryFn extends import('../Selection/Autocomplete/queryAutocomplete.types').QueryFn>({ query, queryParams, queryOptions, queryMap, leadingContent, ...props }: import('../Selection/Autocomplete/queryAutocomplete.types').QueryAutocompleteProps<TFieldValues, TSelectItem, TQueryFn>) => import("react/jsx-runtime").JSX.Element;
20
20
  readonly segment: <TFieldValues extends import('react-hook-form').FieldValues, TKey extends import('react-aria').Key = import('react-aria').Key>(props: import('../../..').ControlledSegmentProps<TFieldValues, TKey>) => import("react/jsx-runtime").JSX.Element;
21
- readonly datePicker: <TFieldValues extends import('react-hook-form').FieldValues>({ fullIso, minValue, maxValue, renderStaticInput, ...props }: import('../DateTime/DatePicker/DatePicker').ControlledDatePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
21
+ readonly datePicker: <TFieldValues extends import('react-hook-form').FieldValues>({ fullIso, granularity, minValue, maxValue, renderStaticInput, ...props }: import('../DateTime/DatePicker/DatePicker').ControlledDatePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
22
22
  readonly dateTimePicker: <TFieldValues extends import('react-hook-form').FieldValues>({ fullIso, renderStaticInput, ...props }: import('../DateTime/DateTimePicker/DateTimePicker').ControlledDateTimePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
23
23
  readonly timePicker: <TFieldValues extends import('react-hook-form').FieldValues>({ renderStaticInput, ...props }: import('../DateTime/TimePicker/TimePicker').ControlledTimePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
24
24
  readonly dateRangePicker: <TFieldValues extends import('react-hook-form').FieldValues>({ fullIso, minValue, maxValue, renderStaticInput, ...props }: import('../DateTime/DateRangePicker/DateRangePicker').ControlledDateRangePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
@@ -94,6 +94,7 @@ function Autocomplete({ renderStaticInput, ...props }) {
94
94
  dataAttributes,
95
95
  renderStatic: true,
96
96
  onStaticInteract: renderRealInput,
97
+ trailingClassName: "pl-1-5",
97
98
  leadingContent: props.leadingContent && /* @__PURE__ */ jsx("div", {
98
99
  className: "ml-input-side-default flex shrink-0 items-center",
99
100
  children: props.leadingContent
@@ -94,6 +94,7 @@ function Select({ renderStaticInput, ...props }) {
94
94
  labelPlacement: "content-row",
95
95
  dataAttributes,
96
96
  renderStatic: true,
97
+ trailingClassName: "pl-1-5",
97
98
  onStaticInteract: renderRealInput,
98
99
  leadingContent: props.leadingContent && /* @__PURE__ */ jsx("div", {
99
100
  className: "ml-input-side-default flex shrink-0 items-center",
@@ -108,7 +108,8 @@ var SelectMobile = ({ ref, error, showSelectionContent, inputClassName, containe
108
108
  rightContent: /* @__PURE__ */ jsx(FormFieldHeaderClose, { onClose: close }),
109
109
  inputClassName,
110
110
  className: "mb-list-height-title-bottom px-list-side-title",
111
- leadingIcon: !hideSearchIcon ? /* @__PURE__ */ jsx(SearchIcon, { className: "size-6" }) : void 0
111
+ leadingIcon: !hideSearchIcon ? /* @__PURE__ */ jsx(SearchIcon, { className: "size-6" }) : void 0,
112
+ size: "default"
112
113
  }), /* @__PURE__ */ jsx(SelectListBox, {
113
114
  ...props,
114
115
  autoFocus: !isSearchable,
@@ -1,5 +1,5 @@
1
- import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
2
1
  import { useSelectItems } from "./useSelectItems.js";
2
+ import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { createContext, use, useCallback, useEffect, useMemo, useRef, useState } from "react";
5
5
  //#region src/components/inputs/Selection/shared/select.context.tsx
@@ -71,7 +71,7 @@ var InputFrame = (props) => {
71
71
  }) : null;
72
72
  const resolvedContentWrapperClassName = contentWrapperClassName ?? inputContentWrapperCva({ as });
73
73
  const contentRow = /* @__PURE__ */ jsxs("div", {
74
- className: clsx("group/input-frame flex min-w-0 w-full items-center gap-input-gap-input-text-to-elements pr-0!", as === "inline" && "h-full", inputSizeCva({
74
+ className: clsx("group/input-frame flex min-w-0 w-full items-center gap-input-gap-input-text-to-elements", as === "inline" && "h-full", inputSizeCva({
75
75
  size,
76
76
  as
77
77
  }), typographySize && typographyCva({ size: typographySize }), contentClassName),
@@ -97,7 +97,7 @@ var InputFrame = (props) => {
97
97
  ]
98
98
  });
99
99
  const trailingRow = hasTrailingContent ? /* @__PURE__ */ jsxs("div", {
100
- className: clsx("flex items-center gap-input-gap-trailing-elements py-0! pl-0!", inputSizeCva({
100
+ className: clsx("flex items-center gap-input-gap-trailing-elements", inputSizeCva({
101
101
  size,
102
102
  as
103
103
  }), !isTrailingInteractive && "pointer-events-none", trailingClassName),
@@ -76,10 +76,9 @@ var BottomSheetBase = ({ isOpen, onOpenChange, onStateChange, isDismissable = tr
76
76
  return /* @__PURE__ */ jsx(AnimatePresence, { children: isOpen && /* @__PURE__ */ jsxs(MotionModalOverlay, {
77
77
  isOpen: true,
78
78
  UNSTABLE_portalContainer: portalContainerRef?.current,
79
- className: clsx("fixed top-0 left-0 z-10 w-screen", containerClassName),
79
+ className: clsx("fixed top-0 left-0 z-10 w-screen h-dvh", containerClassName),
80
80
  onOpenChange,
81
81
  isDismissable,
82
- style: { height: viewport.height },
83
82
  ref: overlayRef,
84
83
  shouldCloseOnInteractOutside,
85
84
  children: [/* @__PURE__ */ jsx(motion.div, {
@@ -189,7 +188,7 @@ var BottomSheetBase = ({ isOpen, onOpenChange, onStateChange, isDismissable = tr
189
188
  initial: { opacity: 0 },
190
189
  exit: { opacity: 0 },
191
190
  ref: setFooterElement,
192
- className: clsx("pointer-events-auto absolute z-50 w-full bg-elevation-fill-default-2", "top-(--visual-viewport-height) left-0 translate-y-[calc(-100%-var(--scroll-position,0px))]"),
191
+ className: clsx("pointer-events-auto absolute z-50 w-full bg-elevation-fill-default-2", "top-[100dvh] left-0 translate-y-[calc(-100%-var(--scroll-position,0px))]"),
193
192
  children: footer
194
193
  })
195
194
  ] })
@@ -1,6 +1,6 @@
1
- import { JSX, Ref } from 'react';
1
+ import { JSX, ReactNode, Ref } from 'react';
2
2
  export interface TooltipEllipsisProps {
3
- text: string;
3
+ text: ReactNode;
4
4
  children: (ref: Ref<HTMLElement> | undefined) => JSX.Element;
5
5
  isDisabled?: boolean;
6
6
  isNonInteractiveTrigger?: boolean;
@@ -11,7 +11,7 @@ import { mergeRefs } from "@react-aria/utils";
11
11
  import { Controller } from "react-hook-form";
12
12
  import { useToggleGroupState } from "react-stately";
13
13
  //#region src/components/segment/Segment.tsx
14
- var SegmentBase = ({ className, items, error, onChange, value, defaultValue, ...rest }) => {
14
+ var SegmentBase = ({ className, items, error, onChange, value, defaultValue, segmentItemClassName, ...rest }) => {
15
15
  const props = {
16
16
  ...rest,
17
17
  defaultSelectedKeys: defaultValue ? Array.isArray(defaultValue) ? defaultValue : [defaultValue] : void 0,
@@ -49,6 +49,7 @@ var SegmentBase = ({ className, items, error, onChange, value, defaultValue, ...
49
49
  style: { gridTemplateColumns },
50
50
  children: items.map((item, index) => /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(SegmentItem, {
51
51
  ...item,
52
+ className: clsx(item.className, segmentItemClassName),
52
53
  isDisabled: item.isDisabled || props.isDisabled,
53
54
  isSelected: state.selectedKeys.has(item.id),
54
55
  onPress: () => {
@@ -1,2 +1,2 @@
1
1
  import { SegmentItem as SegmentItemProps } from './segment.types';
2
- export declare const SegmentItem: ({ label, icon, id, isDisabled, ...props }: SegmentItemProps) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const SegmentItem: ({ label, icon, id, isDisabled, className, ...props }: SegmentItemProps) => import("react/jsx-runtime").JSX.Element;
@@ -4,14 +4,17 @@ import { segmentItemCva } from "./segment.cva.js";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  import { ToggleButton } from "react-aria-components";
6
6
  //#region src/components/segment/SegmentItem.tsx
7
- var SegmentItem = ({ label, icon, id, isDisabled, ...props }) => {
7
+ var SegmentItem = ({ label, icon, id, isDisabled, className, ...props }) => {
8
8
  const IconComponent = icon;
9
9
  const iconOnly = !!(icon && !label);
10
10
  const segmentItemCva$1 = UIStyle.useCva("segment.itemCva", segmentItemCva);
11
11
  return /* @__PURE__ */ jsxs(ToggleButton, {
12
12
  ...props,
13
13
  id,
14
- className: segmentItemCva$1({ iconOnly }),
14
+ className: segmentItemCva$1({
15
+ iconOnly,
16
+ className
17
+ }),
15
18
  isDisabled,
16
19
  children: [icon && /* @__PURE__ */ jsx(IconComponent, { className: "size-6" }), label && /* @__PURE__ */ jsx(Typography, {
17
20
  size: "label-2",
@@ -30,6 +30,7 @@ export type SegmentProps<TKey extends Key = Key> = Omit<ToggleButtonGroupProps &
30
30
  ref?: Ref<HTMLElement>;
31
31
  items: SegmentItem<TKey>[];
32
32
  className?: string;
33
+ segmentItemClassName?: string;
33
34
  error?: string;
34
35
  } & GroupedSegmentProps<TKey>;
35
36
  export type ControlledSegmentProps<TFieldValues extends FieldValues, TKey extends Key = Key> = SegmentProps<TKey> & GroupedSegmentControlProps<TFieldValues, TKey>;
@@ -1,11 +1,13 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { createContext, use } from "react";
2
+ import { createContext, use, useMemo } from "react";
3
3
  //#region src/config/link.context.tsx
4
4
  var LinkContext;
5
5
  (function(_LinkContext) {
6
6
  const LinkContextInternal = createContext(null);
7
7
  _LinkContext.LinkContextProvider = ({ children, LinkComponent }) => {
8
- const value = { LinkComponent };
8
+ const value = useMemo(() => {
9
+ return { LinkComponent };
10
+ }, [LinkComponent]);
9
11
  return /* @__PURE__ */ jsx(LinkContextInternal.Provider, {
10
12
  value,
11
13
  children
@@ -34,7 +34,7 @@ export declare namespace UIConfig {
34
34
  };
35
35
  toggle: Pick<ToggleProps, "variant">;
36
36
  slider: Pick<SliderProps, "minValue" | "maxValue">;
37
- dateInput: Pick<DatePickerProps, "todayIcon" | "todayIconButtonSize" | "todayIconPlacement" | "shouldForceLeadingZeros" | "disableManualEntry" | "autoFixYear"> & {
37
+ dateInput: Pick<DatePickerProps, "todayIcon" | "todayIconButtonSize" | "todayIconPlacement" | "shouldForceLeadingZeros" | "disableManualEntry" | "shouldUpdateDateOnMonthYearChange" | "granularity" | "autoFixYear"> & {
38
38
  calendarIcon?: ReactElement;
39
39
  dateTimeIcon?: ReactElement;
40
40
  timeIcon?: ReactElement;
@@ -55,7 +55,9 @@ var UIConfig;
55
55
  calendarIcon: /* @__PURE__ */ jsx(CalendarIcon, { className: "size-5" }),
56
56
  dateTimeIcon: /* @__PURE__ */ jsx(DateTimeIcon, { className: "size-5" }),
57
57
  timeIcon: /* @__PURE__ */ jsx(ClockIcon, { className: "size-6 text-interactive-text-secondary-idle" }),
58
- setDateValueOnDateSelection: false
58
+ setDateValueOnDateSelection: false,
59
+ granularity: "day",
60
+ shouldUpdateDateOnMonthYearChange: false
59
61
  },
60
62
  actionModal: {
61
63
  titleTypography: {
package/dist/index.js CHANGED
@@ -69,9 +69,9 @@ import { useLongPressRepeat } from "./hooks/useLongPressRepeat.js";
69
69
  import { useScrollableListBox } from "./hooks/useScrollableListBox.js";
70
70
  import { DateTimeUtils } from "./utils/date-time.utils.js";
71
71
  import { FormField } from "./components/inputs/FormField/FormField.js";
72
- import { useDebounceCallback } from "./hooks/useDebounceCallback.js";
73
72
  import { DatePicker } from "./components/inputs/DateTime/DatePicker/DatePicker.js";
74
73
  import { Tag } from "./components/text/Tag/Tag.js";
74
+ import { useDebounceCallback } from "./hooks/useDebounceCallback.js";
75
75
  import { useIntersectionObserver } from "./hooks/useIntersectionObserver.js";
76
76
  import { TextInput } from "./components/inputs/Input/TextInput/TextInput.js";
77
77
  import { Select } from "./components/inputs/Selection/Select/Select.js";
@@ -20,16 +20,17 @@ export declare namespace DateTimeUtils {
20
20
  minute: number;
21
21
  }, locale?: string): string;
22
22
  export function formatCalendarDateTimeLocalized(calendarDateTime: Pick<CalendarDateTime, "day" | "month" | "year" | "hour" | "minute">, locale?: string, options?: LocalizedDateFormatOptions): string;
23
- export function fromISOtoZonedDateTime(isoString: string): ZonedDateTime;
24
- export function fromDateValueToISO(dateValue: DateValue): string;
25
- export function fromLocalToZonedDateTime(date: Date): ZonedDateTime;
26
- export function fromDateValueToLocal(dateValue: DateValue): Date;
23
+ export function fromISOtoZonedDateTime(isoString: string, timeZone?: string): ZonedDateTime;
24
+ export function fromDateValueToISO(dateValue: DateValue, timeZone?: string): string;
25
+ export function fromDateValueToOffsetISO(dateValue: DateValue, timeZone?: string): string;
26
+ export function fromLocalToZonedDateTime(date: Date, timeZone?: string): ZonedDateTime;
27
+ export function fromDateValueToLocal(dateValue: DateValue, timeZone?: string): Date;
27
28
  export function fromCalendarDateToUTCISO(calendarDate: CalendarDate, options?: {
28
29
  endOfDay?: boolean;
29
30
  }): string;
30
31
  export function fromUTCISOToCalendarDate(isoString: string): CalendarDate;
31
32
  export function fromCalendarDateTimeToUTCISO(calendarDateTime: CalendarDateTime): string;
32
- export function fromUTCISOToCalendarDateTime(isoString: string): CalendarDateTime;
33
- export function formatTextDateToCalendarDateTime(textDate: string | null): CalendarDateTime | null;
33
+ export function fromUTCISOToCalendarDateTime(isoString: string, timeZone?: string): CalendarDateTime;
34
+ export function formatTextDateToCalendarDateTime(textDate: string | null, timeZone?: string, locale?: string): CalendarDateTime | null;
34
35
  export {};
35
36
  }
@@ -1,4 +1,5 @@
1
- import { CalendarDate, CalendarDateTime, DateFormatter, fromDate, getLocalTimeZone, parseAbsolute, parseAbsoluteToLocal } from "@internationalized/date";
1
+ import { CalendarDate, CalendarDateTime, DateFormatter, fromDate, getLocalTimeZone, parseAbsolute } from "@internationalized/date";
2
+ import { DateTime } from "luxon";
2
3
  //#region src/utils/date-time.utils.ts
3
4
  var DateTimeUtils;
4
5
  (function(_DateTimeUtils) {
@@ -40,6 +41,20 @@ var DateTimeUtils;
40
41
  hourCycle: "h23",
41
42
  timeZone: "UTC"
42
43
  });
44
+ const getLocaleDateFormat = (locale) => {
45
+ const sampleDate = new Date(Date.UTC(2e3, 10, 22));
46
+ return new Intl.DateTimeFormat(locale, {
47
+ day: "2-digit",
48
+ month: "2-digit",
49
+ year: "numeric",
50
+ timeZone: "UTC"
51
+ }).formatToParts(sampleDate).map((part) => {
52
+ if (part.type === "day") return "dd";
53
+ if (part.type === "month") return "MM";
54
+ if (part.type === "year") return "yyyy";
55
+ return part.value;
56
+ }).join("");
57
+ };
43
58
  const repeatLocalizedFieldLabel = (type, length, locale) => {
44
59
  const placeholderChar = new Intl.DisplayNames(getResolvedLocale(locale), { type: "dateTimeField" }).of(type)?.trim().charAt(0).toLocaleLowerCase(getResolvedLocale(locale));
45
60
  if (!placeholderChar) return null;
@@ -114,20 +129,34 @@ var DateTimeUtils;
114
129
  return formatLocalizedDateParts(getDateTimeFormatter(locale, options), normalizedValue.toDate("UTC"), options);
115
130
  }
116
131
  _DateTimeUtils.formatCalendarDateTimeLocalized = formatCalendarDateTimeLocalized;
117
- function fromISOtoZonedDateTime(isoString) {
118
- return parseAbsoluteToLocal(isoString);
132
+ function resolveTimeZone(timeZone) {
133
+ if (timeZone) return timeZone;
134
+ return getLocalTimeZone();
135
+ }
136
+ function fromISOtoZonedDateTime(isoString, timeZone) {
137
+ return parseAbsolute(isoString, resolveTimeZone(timeZone));
119
138
  }
120
139
  _DateTimeUtils.fromISOtoZonedDateTime = fromISOtoZonedDateTime;
121
- function fromDateValueToISO(dateValue) {
122
- return dateValue.toDate(getLocalTimeZone()).toISOString();
140
+ function fromDateValueToISO(dateValue, timeZone) {
141
+ const resolvedTimeZone = resolveTimeZone(timeZone);
142
+ return dateValue.toDate(resolvedTimeZone).toISOString();
123
143
  }
124
144
  _DateTimeUtils.fromDateValueToISO = fromDateValueToISO;
125
- function fromLocalToZonedDateTime(date) {
126
- return fromDate(date, getLocalTimeZone());
145
+ function fromDateValueToOffsetISO(dateValue, timeZone) {
146
+ const resolvedTimeZone = resolveTimeZone(timeZone);
147
+ const date = dateValue.toDate(resolvedTimeZone);
148
+ const isoString = DateTime.fromJSDate(date, { zone: resolvedTimeZone }).toISO({ includeOffset: true });
149
+ if (isoString) return isoString;
150
+ return date.toISOString();
151
+ }
152
+ _DateTimeUtils.fromDateValueToOffsetISO = fromDateValueToOffsetISO;
153
+ function fromLocalToZonedDateTime(date, timeZone) {
154
+ return fromDate(date, resolveTimeZone(timeZone));
127
155
  }
128
156
  _DateTimeUtils.fromLocalToZonedDateTime = fromLocalToZonedDateTime;
129
- function fromDateValueToLocal(dateValue) {
130
- return dateValue.toDate(getLocalTimeZone());
157
+ function fromDateValueToLocal(dateValue, timeZone) {
158
+ const resolvedTimeZone = resolveTimeZone(timeZone);
159
+ return dateValue.toDate(resolvedTimeZone);
131
160
  }
132
161
  _DateTimeUtils.fromDateValueToLocal = fromDateValueToLocal;
133
162
  function fromCalendarDateToUTCISO(calendarDate, options = {}) {
@@ -144,19 +173,29 @@ var DateTimeUtils;
144
173
  return calendarDateTime.toDate("UTC").toISOString();
145
174
  }
146
175
  _DateTimeUtils.fromCalendarDateTimeToUTCISO = fromCalendarDateTimeToUTCISO;
147
- function fromUTCISOToCalendarDateTime(isoString) {
148
- const zonedDateTime = parseAbsolute(isoString, "UTC");
176
+ function fromUTCISOToCalendarDateTime(isoString, timeZone = "UTC") {
177
+ const zonedDateTime = parseAbsolute(isoString, timeZone);
149
178
  return new CalendarDateTime(zonedDateTime.year, zonedDateTime.month, zonedDateTime.day, zonedDateTime.hour, zonedDateTime.minute, zonedDateTime.second, zonedDateTime.millisecond);
150
179
  }
151
180
  _DateTimeUtils.fromUTCISOToCalendarDateTime = fromUTCISOToCalendarDateTime;
152
- function formatTextDateToCalendarDateTime(textDate) {
181
+ function formatTextDateToCalendarDateTime(textDate, timeZone, locale) {
153
182
  if (!textDate?.includes("hh")) return null;
154
183
  const datePart = textDate.split(",").at(0)?.trim();
155
184
  if (!datePart) return null;
156
- const date = new Date(datePart);
157
- if (!date || date.toString() === "Invalid Date") return null;
158
- const zonedDateTime = fromDate(date, getLocalTimeZone());
159
- return new CalendarDateTime(zonedDateTime.year, zonedDateTime.month, zonedDateTime.day, 0, 0, 0, 0);
185
+ const resolvedTimeZone = resolveTimeZone(timeZone);
186
+ const resolvedLocale = locale || Intl.DateTimeFormat().resolvedOptions().locale;
187
+ const localeDateFormat = getLocaleDateFormat(resolvedLocale);
188
+ const parseOptions = {
189
+ zone: resolvedTimeZone,
190
+ locale: resolvedLocale
191
+ };
192
+ let parsedDateTime = DateTime.fromFormat(datePart, localeDateFormat, parseOptions);
193
+ if (!parsedDateTime.isValid && localeDateFormat.includes("yyyy")) {
194
+ const shortYearFormat = localeDateFormat.replace("yyyy", "yy");
195
+ parsedDateTime = DateTime.fromFormat(datePart, shortYearFormat, parseOptions);
196
+ }
197
+ if (!parsedDateTime.isValid) return null;
198
+ return new CalendarDateTime(parsedDateTime.year, parsedDateTime.month, parsedDateTime.day, 0, 0, 0, 0);
160
199
  }
161
200
  _DateTimeUtils.formatTextDateToCalendarDateTime = formatTextDateToCalendarDateTime;
162
201
  })(DateTimeUtils || (DateTimeUtils = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@povio/ui",
3
- "version": "2.2.9-rc.42",
3
+ "version": "2.2.9-rc.44",
4
4
  "type": "module",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -47,9 +47,9 @@
47
47
  "react-responsive": "^10.0.1",
48
48
  "react-stately": "^3.44.0",
49
49
  "react-toastify": "^11.0.5",
50
- "tailwindcss": "^4.2.1",
51
- "tailwindcss-react-aria-components": "^2.0.1",
52
- "zod": "^4.3.5"
50
+ "tailwindcss": "^4.2.4",
51
+ "tailwindcss-react-aria-components": "^2.1.0",
52
+ "zod": "^4.4.3"
53
53
  },
54
54
  "peerDependencies": {
55
55
  "@casl/ability": "^6.7.3",
@@ -1,9 +0,0 @@
1
- //#region src/components/inputs/DateTime/shared/dateSegment.utils.ts
2
- var getTimeSegmentValue = (segment, fallbackValue = 0) => {
3
- if (!segment) return fallbackValue;
4
- const parsedValue = Number.parseInt(segment.text, 10);
5
- if (Number.isFinite(parsedValue)) return parsedValue;
6
- return Number.isFinite(segment.value) ? segment.value ?? fallbackValue : fallbackValue;
7
- };
8
- //#endregion
9
- export { getTimeSegmentValue };