@trackunit/react-date-and-time-components 2.1.4 → 2.1.5
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/index.cjs.js
CHANGED
|
@@ -96,7 +96,7 @@ const MS_PER_HOUR = 60 * 60 * 1000;
|
|
|
96
96
|
/**
|
|
97
97
|
* DateTime renders a locale-aware, formatted date and/or time inside a semantic `<time>` element.
|
|
98
98
|
* It supports absolute formatting via `TemporalFormat` presets (e.g., `DateTimeFormat.DATE`, `DateTimeFormat.DATE_LONG_TIME`)
|
|
99
|
-
* and relative "time ago" display via the `fromNow` prop. Timezone-aware formatting is
|
|
99
|
+
* and relative "time ago" display via the `fromNow` prop. Timezone-aware formatting is handled automatically via the user's preferred timezone.
|
|
100
100
|
*
|
|
101
101
|
* ### When to use
|
|
102
102
|
* Use DateTime whenever you need to display a date, time, or relative timestamp in the UI — for example, "Last seen 3 hours ago" or "Feb 17, 2026".
|
|
@@ -124,20 +124,22 @@ const MS_PER_HOUR = 60 * 60 * 1000;
|
|
|
124
124
|
* ```
|
|
125
125
|
* @param {DateTimeProps} props - The props for the DateTime component
|
|
126
126
|
*/
|
|
127
|
-
const DateTime = ({ value, format, className, style, fromNow = false, withTitle = false, titleFormat, timezone, "data-testid": dataTestId, subtle = false, ref, ...rest }) => {
|
|
127
|
+
const DateTime = ({ value, format, className, style, fromNow = false, withTitle = false, titleFormat, timezone: timezoneProp, "data-testid": dataTestId, subtle = false, ref, ...rest }) => {
|
|
128
128
|
const { t } = useTranslation();
|
|
129
129
|
const locale = reactDateAndTimeHooks.useLocale();
|
|
130
|
+
const { preferred: preferredTimezone } = reactDateAndTimeHooks.useTimezone();
|
|
131
|
+
const timezone = timezoneProp ?? preferredTimezone;
|
|
130
132
|
const nowDate = react.useMemo(() => new Date(), []);
|
|
131
133
|
const date = sharedUtils.truthy(value) ? dateAndTimeUtils.toDateUtil(value) : nowDate;
|
|
132
|
-
const newDateTime = dateAndTimeUtils.formatDateUtil(date, format, timezone
|
|
133
|
-
const titleDateTime = withTitle ? dateAndTimeUtils.formatDateUtil(date, titleFormat, timezone
|
|
134
|
+
const newDateTime = dateAndTimeUtils.formatDateUtil(date, format, timezone.id, locale);
|
|
135
|
+
const titleDateTime = withTitle ? dateAndTimeUtils.formatDateUtil(date, titleFormat, timezone.id, locale) : undefined;
|
|
134
136
|
const getTimeSince = react.useCallback((from, to) => {
|
|
135
137
|
const same = dateAndTimeUtils.isEqualUtil(from, to);
|
|
136
138
|
if (same) {
|
|
137
139
|
return t("dateTime.instant.now");
|
|
138
140
|
}
|
|
139
|
-
return dateAndTimeUtils.timeSinceAuto(from, to, timezone
|
|
140
|
-
}, [locale, t, timezone
|
|
141
|
+
return dateAndTimeUtils.timeSinceAuto(from, to, timezone.id, locale);
|
|
142
|
+
}, [locale, t, timezone.id]);
|
|
141
143
|
const dateValue = react.useMemo(() => {
|
|
142
144
|
return fromNow ? getTimeSince(date, nowDate) : newDateTime;
|
|
143
145
|
}, [date, fromNow, getTimeSince, newDateTime, nowDate]);
|
|
@@ -266,7 +268,7 @@ const DayPicker = ({ onDaySelect, disabledDays, selectedDay, language, className
|
|
|
266
268
|
* @param {DayRangePickerProps} props - The props for the DayRangePicker component
|
|
267
269
|
* @returns {ReactElement} DayRangePicker component
|
|
268
270
|
*/
|
|
269
|
-
const DayRangePicker = ({ onRangeSelect, selectedDays, disabledDays, "data-testid": dataTestId, language, className, style, classNameCalendar,
|
|
271
|
+
const DayRangePicker = ({ onRangeSelect, selectedDays, disabledDays, "data-testid": dataTestId, language, className, style, classNameCalendar, cancelButtonLabel, onClose, ref, }) => {
|
|
270
272
|
const [newRange, setNewRange] = react.useState(selectedDays ?? { start: undefined, end: undefined });
|
|
271
273
|
const [t] = useTranslation();
|
|
272
274
|
const { subtract } = reactDateAndTimeHooks.useDateAndTime();
|
|
@@ -688,7 +690,7 @@ const isTemporalDirection = (direction) => {
|
|
|
688
690
|
* ```
|
|
689
691
|
* @param {DayRangeSelectProps} props - The props for the DayRangeSelect component
|
|
690
692
|
*/
|
|
691
|
-
const DayRangeSelect = ({ className, "data-testid": dataTestId, disabled = false, selectedDateRange, onRangeSelect, allowedDirection = undefined, initialDateRangeOptions, showDateRangeSearch = true, showCustomDateRangeOption = true,
|
|
693
|
+
const DayRangeSelect = ({ className, "data-testid": dataTestId, disabled = false, selectedDateRange, onRangeSelect, allowedDirection = undefined, initialDateRangeOptions, showDateRangeSearch = true, showCustomDateRangeOption = true, maxDaysInRange, disabledDays, size = "medium", fullWidth = false, actionButton, popoverPlacement = "bottom-start", }) => {
|
|
692
694
|
const [t] = useTranslation();
|
|
693
695
|
const parseTemporalPeriodFromText = useParseTemporalPeriodFromText();
|
|
694
696
|
const filterTemporalPeriodsInRange = useFilterTemporalPeriodsInRange();
|
|
@@ -790,7 +792,7 @@ const DayRangeSelect = ({ className, "data-testid": dataTestId, disabled = false
|
|
|
790
792
|
start: dateRange.start ?? undefined,
|
|
791
793
|
end: dateRange.end ?? undefined,
|
|
792
794
|
}
|
|
793
|
-
: undefined, closeMenu), selectedDays: currentSelectedRange?.dateRange
|
|
795
|
+
: undefined, closeMenu), selectedDays: currentSelectedRange?.dateRange }) }));
|
|
794
796
|
} })] }));
|
|
795
797
|
};
|
|
796
798
|
|
package/index.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { registerTranslations, useNamespaceTranslation } from '@trackunit/i18n-library-translation';
|
|
3
3
|
import { toDateUtil, formatDateUtil, isEqualUtil, timeSinceAuto, getHourCycle } from '@trackunit/date-and-time-utils';
|
|
4
|
-
import { useLocale,
|
|
4
|
+
import { useLocale, useTimezone, useDateAndTime } from '@trackunit/react-date-and-time-hooks';
|
|
5
5
|
import { truthy, DateTimeFormat, nonNullable, objectKeys } from '@trackunit/shared-utils';
|
|
6
6
|
import { useMemo, useCallback, useState, useEffect, useRef, Children, isValidElement } from 'react';
|
|
7
7
|
import { twMerge } from 'tailwind-merge';
|
|
@@ -94,7 +94,7 @@ const MS_PER_HOUR = 60 * 60 * 1000;
|
|
|
94
94
|
/**
|
|
95
95
|
* DateTime renders a locale-aware, formatted date and/or time inside a semantic `<time>` element.
|
|
96
96
|
* It supports absolute formatting via `TemporalFormat` presets (e.g., `DateTimeFormat.DATE`, `DateTimeFormat.DATE_LONG_TIME`)
|
|
97
|
-
* and relative "time ago" display via the `fromNow` prop. Timezone-aware formatting is
|
|
97
|
+
* and relative "time ago" display via the `fromNow` prop. Timezone-aware formatting is handled automatically via the user's preferred timezone.
|
|
98
98
|
*
|
|
99
99
|
* ### When to use
|
|
100
100
|
* Use DateTime whenever you need to display a date, time, or relative timestamp in the UI — for example, "Last seen 3 hours ago" or "Feb 17, 2026".
|
|
@@ -122,20 +122,22 @@ const MS_PER_HOUR = 60 * 60 * 1000;
|
|
|
122
122
|
* ```
|
|
123
123
|
* @param {DateTimeProps} props - The props for the DateTime component
|
|
124
124
|
*/
|
|
125
|
-
const DateTime = ({ value, format, className, style, fromNow = false, withTitle = false, titleFormat, timezone, "data-testid": dataTestId, subtle = false, ref, ...rest }) => {
|
|
125
|
+
const DateTime = ({ value, format, className, style, fromNow = false, withTitle = false, titleFormat, timezone: timezoneProp, "data-testid": dataTestId, subtle = false, ref, ...rest }) => {
|
|
126
126
|
const { t } = useTranslation();
|
|
127
127
|
const locale = useLocale();
|
|
128
|
+
const { preferred: preferredTimezone } = useTimezone();
|
|
129
|
+
const timezone = timezoneProp ?? preferredTimezone;
|
|
128
130
|
const nowDate = useMemo(() => new Date(), []);
|
|
129
131
|
const date = truthy(value) ? toDateUtil(value) : nowDate;
|
|
130
|
-
const newDateTime = formatDateUtil(date, format, timezone
|
|
131
|
-
const titleDateTime = withTitle ? formatDateUtil(date, titleFormat, timezone
|
|
132
|
+
const newDateTime = formatDateUtil(date, format, timezone.id, locale);
|
|
133
|
+
const titleDateTime = withTitle ? formatDateUtil(date, titleFormat, timezone.id, locale) : undefined;
|
|
132
134
|
const getTimeSince = useCallback((from, to) => {
|
|
133
135
|
const same = isEqualUtil(from, to);
|
|
134
136
|
if (same) {
|
|
135
137
|
return t("dateTime.instant.now");
|
|
136
138
|
}
|
|
137
|
-
return timeSinceAuto(from, to, timezone
|
|
138
|
-
}, [locale, t, timezone
|
|
139
|
+
return timeSinceAuto(from, to, timezone.id, locale);
|
|
140
|
+
}, [locale, t, timezone.id]);
|
|
139
141
|
const dateValue = useMemo(() => {
|
|
140
142
|
return fromNow ? getTimeSince(date, nowDate) : newDateTime;
|
|
141
143
|
}, [date, fromNow, getTimeSince, newDateTime, nowDate]);
|
|
@@ -264,7 +266,7 @@ const DayPicker = ({ onDaySelect, disabledDays, selectedDay, language, className
|
|
|
264
266
|
* @param {DayRangePickerProps} props - The props for the DayRangePicker component
|
|
265
267
|
* @returns {ReactElement} DayRangePicker component
|
|
266
268
|
*/
|
|
267
|
-
const DayRangePicker = ({ onRangeSelect, selectedDays, disabledDays, "data-testid": dataTestId, language, className, style, classNameCalendar,
|
|
269
|
+
const DayRangePicker = ({ onRangeSelect, selectedDays, disabledDays, "data-testid": dataTestId, language, className, style, classNameCalendar, cancelButtonLabel, onClose, ref, }) => {
|
|
268
270
|
const [newRange, setNewRange] = useState(selectedDays ?? { start: undefined, end: undefined });
|
|
269
271
|
const [t] = useTranslation();
|
|
270
272
|
const { subtract } = useDateAndTime();
|
|
@@ -686,7 +688,7 @@ const isTemporalDirection = (direction) => {
|
|
|
686
688
|
* ```
|
|
687
689
|
* @param {DayRangeSelectProps} props - The props for the DayRangeSelect component
|
|
688
690
|
*/
|
|
689
|
-
const DayRangeSelect = ({ className, "data-testid": dataTestId, disabled = false, selectedDateRange, onRangeSelect, allowedDirection = undefined, initialDateRangeOptions, showDateRangeSearch = true, showCustomDateRangeOption = true,
|
|
691
|
+
const DayRangeSelect = ({ className, "data-testid": dataTestId, disabled = false, selectedDateRange, onRangeSelect, allowedDirection = undefined, initialDateRangeOptions, showDateRangeSearch = true, showCustomDateRangeOption = true, maxDaysInRange, disabledDays, size = "medium", fullWidth = false, actionButton, popoverPlacement = "bottom-start", }) => {
|
|
690
692
|
const [t] = useTranslation();
|
|
691
693
|
const parseTemporalPeriodFromText = useParseTemporalPeriodFromText();
|
|
692
694
|
const filterTemporalPeriodsInRange = useFilterTemporalPeriodsInRange();
|
|
@@ -788,7 +790,7 @@ const DayRangeSelect = ({ className, "data-testid": dataTestId, disabled = false
|
|
|
788
790
|
start: dateRange.start ?? undefined,
|
|
789
791
|
end: dateRange.end ?? undefined,
|
|
790
792
|
}
|
|
791
|
-
: undefined, closeMenu), selectedDays: currentSelectedRange?.dateRange
|
|
793
|
+
: undefined, closeMenu), selectedDays: currentSelectedRange?.dateRange }) }));
|
|
792
794
|
} })] }));
|
|
793
795
|
};
|
|
794
796
|
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-date-and-time-components",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.5",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=24.x"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@trackunit/react-components": "2.1.
|
|
11
|
-
"@trackunit/date-and-time-utils": "1.13.
|
|
12
|
-
"@trackunit/react-date-and-time-hooks": "2.1.
|
|
13
|
-
"@trackunit/css-class-variance-utilities": "1.13.
|
|
14
|
-
"@trackunit/ui-icons": "1.13.
|
|
15
|
-
"@trackunit/shared-utils": "1.15.
|
|
16
|
-
"@trackunit/i18n-library-translation": "2.0.
|
|
17
|
-
"@trackunit/react-form-components": "2.1.
|
|
10
|
+
"@trackunit/react-components": "2.1.3",
|
|
11
|
+
"@trackunit/date-and-time-utils": "1.13.14",
|
|
12
|
+
"@trackunit/react-date-and-time-hooks": "2.1.4",
|
|
13
|
+
"@trackunit/css-class-variance-utilities": "1.13.13",
|
|
14
|
+
"@trackunit/ui-icons": "1.13.14",
|
|
15
|
+
"@trackunit/shared-utils": "1.15.13",
|
|
16
|
+
"@trackunit/i18n-library-translation": "2.0.5",
|
|
17
|
+
"@trackunit/react-form-components": "2.1.4",
|
|
18
18
|
"string-ts": "^2.0.0",
|
|
19
19
|
"tailwind-merge": "^2.0.0",
|
|
20
20
|
"react-calendar": "^6.0.0"
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { CommonProps, Refable, type Styleable } from "@trackunit/react-components";
|
|
2
2
|
import { DateRange } from "@trackunit/date-and-time-utils";
|
|
3
3
|
import { ReactElement } from "react";
|
|
4
|
-
import { TimeZone } from "../TimeZone";
|
|
5
4
|
import { DisabledDaysMatcher } from "./DayPicker";
|
|
6
5
|
export interface DayRangePickerProps extends CommonProps, Refable<HTMLDivElement>, Styleable {
|
|
7
6
|
/**
|
|
@@ -20,10 +19,6 @@ export interface DayRangePickerProps extends CommonProps, Refable<HTMLDivElement
|
|
|
20
19
|
* Set the language
|
|
21
20
|
*/
|
|
22
21
|
language: string;
|
|
23
|
-
/**
|
|
24
|
-
* Shown time ranges will take timezone into consideration
|
|
25
|
-
*/
|
|
26
|
-
timezone?: TimeZone;
|
|
27
22
|
/**
|
|
28
23
|
* The label for the cancel button
|
|
29
24
|
*/
|
|
@@ -64,4 +59,4 @@ export interface DayRangePickerProps extends CommonProps, Refable<HTMLDivElement
|
|
|
64
59
|
* @param {DayRangePickerProps} props - The props for the DayRangePicker component
|
|
65
60
|
* @returns {ReactElement} DayRangePicker component
|
|
66
61
|
*/
|
|
67
|
-
export declare const DayRangePicker: ({ onRangeSelect, selectedDays, disabledDays, "data-testid": dataTestId, language, className, style, classNameCalendar,
|
|
62
|
+
export declare const DayRangePicker: ({ onRangeSelect, selectedDays, disabledDays, "data-testid": dataTestId, language, className, style, classNameCalendar, cancelButtonLabel, onClose, ref, }: DayRangePickerProps) => ReactElement;
|
|
@@ -35,10 +35,6 @@ export type DayRangeSelectProps = CommonProps & {
|
|
|
35
35
|
* Whether to show the custom date range option with a calendar picker.
|
|
36
36
|
*/
|
|
37
37
|
showCustomDateRangeOption?: boolean;
|
|
38
|
-
/**
|
|
39
|
-
* The timezone for the date range picker.
|
|
40
|
-
*/
|
|
41
|
-
timezone?: DayRangePickerProps["timezone"];
|
|
42
38
|
/**
|
|
43
39
|
* The maximum amount of days that can be selected
|
|
44
40
|
*/
|
|
@@ -92,4 +88,4 @@ export type DayRangeSelectProps = CommonProps & {
|
|
|
92
88
|
* ```
|
|
93
89
|
* @param {DayRangeSelectProps} props - The props for the DayRangeSelect component
|
|
94
90
|
*/
|
|
95
|
-
export declare const DayRangeSelect: ({ className, "data-testid": dataTestId, disabled, selectedDateRange, onRangeSelect, allowedDirection, initialDateRangeOptions, showDateRangeSearch, showCustomDateRangeOption,
|
|
91
|
+
export declare const DayRangeSelect: ({ className, "data-testid": dataTestId, disabled, selectedDateRange, onRangeSelect, allowedDirection, initialDateRangeOptions, showDateRangeSearch, showCustomDateRangeOption, maxDaysInRange, disabledDays, size, fullWidth, actionButton, popoverPlacement, }: DayRangeSelectProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -28,22 +28,27 @@ export interface DateTimeProps extends CommonProps, Refable<HTMLTimeElement>, St
|
|
|
28
28
|
* Custom `TemporalFormat` for the hover `title` attribute. Only used when `withTitle` is true.
|
|
29
29
|
*/
|
|
30
30
|
titleFormat?: TemporalFormat;
|
|
31
|
-
/**
|
|
32
|
-
* A `TimeZone` object to format the date in a specific timezone rather than the user's local timezone.
|
|
33
|
-
*/
|
|
34
|
-
timezone?: TimeZone;
|
|
35
31
|
/**
|
|
36
32
|
* When true, renders the text in a muted neutral color for less visual emphasis.
|
|
37
33
|
*
|
|
38
34
|
* @default false
|
|
39
35
|
*/
|
|
40
36
|
subtle?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Explicit timezone override. When provided, this takes precedence over the automatically resolved
|
|
39
|
+
* timezone from the user's preference context. Useful for showing a date in a fixed timezone
|
|
40
|
+
* regardless of user settings (e.g. a contract's original timezone).
|
|
41
|
+
*
|
|
42
|
+
* In most cases you do not need this — the component resolves the correct timezone automatically
|
|
43
|
+
* via `AssetTimezoneProvider` and user preference context.
|
|
44
|
+
*/
|
|
45
|
+
timezone?: TimeZone;
|
|
41
46
|
}
|
|
42
47
|
export declare const MS_PER_HOUR: number;
|
|
43
48
|
/**
|
|
44
49
|
* DateTime renders a locale-aware, formatted date and/or time inside a semantic `<time>` element.
|
|
45
50
|
* It supports absolute formatting via `TemporalFormat` presets (e.g., `DateTimeFormat.DATE`, `DateTimeFormat.DATE_LONG_TIME`)
|
|
46
|
-
* and relative "time ago" display via the `fromNow` prop. Timezone-aware formatting is
|
|
51
|
+
* and relative "time ago" display via the `fromNow` prop. Timezone-aware formatting is handled automatically via the user's preferred timezone.
|
|
47
52
|
*
|
|
48
53
|
* ### When to use
|
|
49
54
|
* Use DateTime whenever you need to display a date, time, or relative timestamp in the UI — for example, "Last seen 3 hours ago" or "Feb 17, 2026".
|
|
@@ -71,4 +76,4 @@ export declare const MS_PER_HOUR: number;
|
|
|
71
76
|
* ```
|
|
72
77
|
* @param {DateTimeProps} props - The props for the DateTime component
|
|
73
78
|
*/
|
|
74
|
-
export declare const DateTime: ({ value, format, className, style, fromNow, withTitle, titleFormat, timezone, "data-testid": dataTestId, subtle, ref, ...rest }: DateTimeProps) => import("react/jsx-runtime").JSX.Element;
|
|
79
|
+
export declare const DateTime: ({ value, format, className, style, fromNow, withTitle, titleFormat, timezone: timezoneProp, "data-testid": dataTestId, subtle, ref, ...rest }: DateTimeProps) => import("react/jsx-runtime").JSX.Element;
|