@carlonicora/nextjs-jsonapi 6.24.0 → 6.26.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/dist/{BlockNoteEditor-MONT74RQ.js → BlockNoteEditor-JHXDOCS5.js} +28 -25
- package/dist/BlockNoteEditor-JHXDOCS5.js.map +1 -0
- package/dist/{BlockNoteEditor-ENDOVTAW.mjs → BlockNoteEditor-RVDSB6TF.mjs} +13 -10
- package/dist/{BlockNoteEditor-ENDOVTAW.mjs.map → BlockNoteEditor-RVDSB6TF.mjs.map} +1 -1
- package/dist/{BlockNoteViewer-2TJZ6JET.mjs → BlockNoteViewer-76CKL6W5.mjs} +8 -6
- package/dist/{BlockNoteViewer-2TJZ6JET.mjs.map → BlockNoteViewer-76CKL6W5.mjs.map} +1 -1
- package/dist/{BlockNoteViewer-K2HBF3IP.js → BlockNoteViewer-B25WKYQP.js} +9 -7
- package/dist/BlockNoteViewer-B25WKYQP.js.map +1 -0
- package/dist/JsonApiRequest-OKNQZLS6.js +26 -0
- package/dist/{JsonApiRequest-KC6DOHKT.js.map → JsonApiRequest-OKNQZLS6.js.map} +1 -1
- package/dist/{JsonApiRequest-ADLBJ5RX.mjs → JsonApiRequest-WNPDS356.mjs} +2 -2
- package/dist/billing/index.js +504 -517
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +20 -33
- package/dist/billing/index.mjs.map +1 -1
- package/dist/{chunk-VNUT2D27.mjs → chunk-2PWYG2WJ.mjs} +2 -2
- package/dist/{chunk-W4ML6D2X.mjs → chunk-3U7YJ73T.mjs} +7 -7
- package/dist/{chunk-BQ2WAG4K.js → chunk-3VNDFKT7.js} +19 -19
- package/dist/{chunk-BQ2WAG4K.js.map → chunk-3VNDFKT7.js.map} +1 -1
- package/dist/{chunk-BE6UMM5X.mjs → chunk-47HNJQ7U.mjs} +3 -3
- package/dist/chunk-5T2AQMQ2.mjs +90 -0
- package/dist/chunk-5T2AQMQ2.mjs.map +1 -0
- package/dist/{chunk-A5M3MORY.js → chunk-5WM72MLE.js} +3 -3
- package/dist/{chunk-A5M3MORY.js.map → chunk-5WM72MLE.js.map} +1 -1
- package/dist/{chunk-OZADFYE7.mjs → chunk-64REWDSK.mjs} +308 -241
- package/dist/chunk-64REWDSK.mjs.map +1 -0
- package/dist/{chunk-S7SPAC6X.mjs → chunk-73NKUBMP.mjs} +3 -3
- package/dist/chunk-743M4TIB.mjs +76 -0
- package/dist/chunk-743M4TIB.mjs.map +1 -0
- package/dist/{chunk-HN7L6RRW.js → chunk-77JC2UCF.js} +903 -955
- package/dist/chunk-77JC2UCF.js.map +1 -0
- package/dist/{chunk-7OIWOPM5.mjs → chunk-7MGXQIEP.mjs} +4 -3
- package/dist/chunk-7MGXQIEP.mjs.map +1 -0
- package/dist/{chunk-YTDGYI62.mjs → chunk-DWPHHUMV.mjs} +3 -3
- package/dist/{chunk-SO3YUCL6.js → chunk-F3EVYBMA.js} +6 -5
- package/dist/chunk-F3EVYBMA.js.map +1 -0
- package/dist/{chunk-53SD4YRF.js → chunk-FBHUUPRV.js} +5 -5
- package/dist/{chunk-53SD4YRF.js.map → chunk-FBHUUPRV.js.map} +1 -1
- package/dist/{chunk-T6G2F2BK.mjs → chunk-FJUKLVVX.mjs} +16 -68
- package/dist/chunk-FJUKLVVX.mjs.map +1 -0
- package/dist/chunk-HROKKUBQ.js +156 -0
- package/dist/chunk-HROKKUBQ.js.map +1 -0
- package/dist/{chunk-BDWV4KYR.js → chunk-JE6QWCNE.js} +1386 -1319
- package/dist/chunk-JE6QWCNE.js.map +1 -0
- package/dist/{chunk-RCOKQ3R4.js → chunk-LNO2JLU3.js} +2 -2
- package/dist/{chunk-RCOKQ3R4.js.map → chunk-LNO2JLU3.js.map} +1 -1
- package/dist/{chunk-TMV7TL7O.mjs → chunk-M7YK5CCE.mjs} +8 -6
- package/dist/{chunk-TMV7TL7O.mjs.map → chunk-M7YK5CCE.mjs.map} +1 -1
- package/dist/{chunk-GMMDXINC.js → chunk-N3NQS7X6.js} +12 -12
- package/dist/{chunk-GMMDXINC.js.map → chunk-N3NQS7X6.js.map} +1 -1
- package/dist/chunk-NP3AFULU.js +76 -0
- package/dist/chunk-NP3AFULU.js.map +1 -0
- package/dist/{chunk-TNTCLVUR.js → chunk-ONU4WCDG.js} +17 -15
- package/dist/chunk-ONU4WCDG.js.map +1 -0
- package/dist/{chunk-YSE2Z4RB.js → chunk-PQQFOONG.js} +12 -12
- package/dist/{chunk-YSE2Z4RB.js.map → chunk-PQQFOONG.js.map} +1 -1
- package/dist/chunk-RW6XZGZG.mjs +156 -0
- package/dist/chunk-RW6XZGZG.mjs.map +1 -0
- package/dist/chunk-SYMI4IDW.js +90 -0
- package/dist/chunk-SYMI4IDW.js.map +1 -0
- package/dist/{chunk-N2BFT7KI.mjs → chunk-W7U6O3OE.mjs} +2 -71
- package/dist/chunk-W7U6O3OE.mjs.map +1 -0
- package/dist/{chunk-YMCL3JXZ.mjs → chunk-YPBIPE2B.mjs} +2 -2
- package/dist/{chunk-P7L6OFX5.js → chunk-Z6T2575A.js} +12 -81
- package/dist/chunk-Z6T2575A.js.map +1 -0
- package/dist/client/index.js +13 -10
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +17 -14
- package/dist/components/forms/DatePickerPopover.d.ts.map +1 -1
- package/dist/components/forms/DateRangeSelector.d.ts.map +1 -1
- package/dist/components/forms/FormDate.d.ts.map +1 -1
- package/dist/components/forms/FormDateTime.d.ts.map +1 -1
- package/dist/components/forms/time-cycle.d.ts +14 -0
- package/dist/components/forms/time-cycle.d.ts.map +1 -0
- package/dist/components/index.js +11 -8
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +10 -7
- package/dist/components/tables/cells/cell.date.d.ts.map +1 -1
- package/dist/components/tables/cells/cell.dateTime.d.ts.map +1 -1
- package/dist/contexts/DateLocaleContext.d.ts +56 -0
- package/dist/contexts/DateLocaleContext.d.ts.map +1 -0
- package/dist/contexts/index.d.ts +1 -0
- package/dist/contexts/index.d.ts.map +1 -1
- package/dist/contexts/index.js +24 -8
- package/dist/contexts/index.js.map +1 -1
- package/dist/contexts/index.mjs +23 -7
- package/dist/core/index.js +17 -6
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +19 -8
- package/dist/date-locale/index.d.ts +2 -0
- package/dist/date-locale/index.d.ts.map +1 -0
- package/dist/date-locale/index.js +21 -0
- package/dist/date-locale/index.js.map +1 -0
- package/dist/date-locale/index.mjs +21 -0
- package/dist/email-automations/index.js +131 -123
- package/dist/email-automations/index.js.map +1 -1
- package/dist/email-automations/index.mjs +23 -15
- package/dist/email-automations/index.mjs.map +1 -1
- package/dist/features/account-deletion/components/AccountDeletionAdminTrigger.d.ts.map +1 -1
- package/dist/features/analytics/components/AnalyticsJourneyContainer.d.ts.map +1 -1
- package/dist/features/analytics/components/AnalyticsSessionsTable.d.ts.map +1 -1
- package/dist/features/analytics/index.js +154 -147
- package/dist/features/analytics/index.js.map +1 -1
- package/dist/features/analytics/index.mjs +32 -25
- package/dist/features/analytics/index.mjs.map +1 -1
- package/dist/features/analytics/server.js +11 -9
- package/dist/features/analytics/server.js.map +1 -1
- package/dist/features/analytics/server.mjs +9 -7
- package/dist/features/analytics/server.mjs.map +1 -1
- package/dist/features/billing/components/utils/date.d.ts +3 -3
- package/dist/features/billing/components/utils/format-options.d.ts +6 -4
- package/dist/features/billing/components/utils/format-options.d.ts.map +1 -1
- package/dist/features/billing/components/utils/useBillingFormatOptions.d.ts +5 -1
- package/dist/features/billing/components/utils/useBillingFormatOptions.d.ts.map +1 -1
- package/dist/features/billing/stripe-usage/components/details/UsageSummaryCard.d.ts.map +1 -1
- package/dist/features/billing/stripe-usage/components/lists/UsageHistoryTable.d.ts.map +1 -1
- package/dist/features/blog/components/admin/BlogTranslationStatus.d.ts.map +1 -1
- package/dist/features/blog/components/public/BlogPostMeta.d.ts.map +1 -1
- package/dist/features/blog/hooks/useBlogPostTableStructure.d.ts.map +1 -1
- package/dist/features/blog/index.js +168 -162
- package/dist/features/blog/index.js.map +1 -1
- package/dist/features/blog/index.mjs +25 -19
- package/dist/features/blog/index.mjs.map +1 -1
- package/dist/features/blog/server.js +29 -27
- package/dist/features/blog/server.js.map +1 -1
- package/dist/features/blog/server.mjs +8 -6
- package/dist/features/blog/server.mjs.map +1 -1
- package/dist/features/email-automation/hooks/useEmailAutomationEnrollmentTableStructure.d.ts.map +1 -1
- package/dist/features/handbook/components/parts/HandbookIndexStatus.d.ts.map +1 -1
- package/dist/features/help/components/HelpArticleBody.d.ts.map +1 -1
- package/dist/features/help/index.js +48 -43
- package/dist/features/help/index.js.map +1 -1
- package/dist/features/help/index.mjs +15 -10
- package/dist/features/help/index.mjs.map +1 -1
- package/dist/features/notification/components/notifications/Notification.d.ts +2 -1
- package/dist/features/notification/components/notifications/Notification.d.ts.map +1 -1
- package/dist/features/notification/contexts/NotificationContext.d.ts.map +1 -1
- package/dist/features/notification/hooks/useNotificationTableStructure.d.ts.map +1 -1
- package/dist/features/oauth/components/OAuthClientCard.d.ts.map +1 -1
- package/dist/features/oauth/components/OAuthClientDetail.d.ts.map +1 -1
- package/dist/features/tokenusage/index.js +133 -130
- package/dist/features/tokenusage/index.js.map +1 -1
- package/dist/features/tokenusage/index.mjs +10 -7
- package/dist/features/tokenusage/index.mjs.map +1 -1
- package/dist/features/tokenusage/lib/formatters.d.ts +6 -3
- package/dist/features/tokenusage/lib/formatters.d.ts.map +1 -1
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +23 -11
- package/dist/local-transport-AT4TE264.js +15 -0
- package/dist/{local-transport-MJPOKPTU.js.map → local-transport-AT4TE264.js.map} +1 -1
- package/dist/{local-transport-RVD4FZGA.mjs → local-transport-KWEUZ4GX.mjs} +5 -5
- package/dist/offline/index.js +56 -54
- package/dist/offline/index.js.map +1 -1
- package/dist/offline/index.mjs +23 -21
- package/dist/offline/index.mjs.map +1 -1
- package/dist/{request-4AWGPIGH.mjs → request-6GAIWWTG.mjs} +2 -2
- package/dist/{request-H5FZBZA2.js → request-BWO4Y434.js} +3 -3
- package/dist/{request-H5FZBZA2.js.map → request-BWO4Y434.js.map} +1 -1
- package/dist/server/ServerSession.d.ts +2 -0
- package/dist/server/ServerSession.d.ts.map +1 -1
- package/dist/server/index.js +10 -8
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +9 -7
- package/dist/utils/date-formatter.d.ts +45 -4
- package/dist/utils/date-formatter.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/toast.d.ts +2 -0
- package/dist/utils/toast.d.ts.map +1 -1
- package/dist/write-through-KNRI5L4V.mjs +15 -0
- package/dist/write-through-KNRI5L4V.mjs.map +1 -0
- package/dist/write-through-MYHQ6GJU.js +15 -0
- package/dist/{write-through-HE2QSOVI.js.map → write-through-MYHQ6GJU.js.map} +1 -1
- package/messages/en.json +1 -0
- package/messages/it.json +1 -0
- package/package.json +6 -1
- package/src/components/forms/DatePickerPopover.tsx +5 -3
- package/src/components/forms/DateRangeSelector.tsx +9 -7
- package/src/components/forms/FormDate.tsx +5 -3
- package/src/components/forms/FormDateTime.tsx +75 -39
- package/src/components/forms/__tests__/time-cycle.spec.ts +37 -0
- package/src/components/forms/time-cycle.ts +27 -0
- package/src/components/tables/cells/cell.date.tsx +3 -5
- package/src/components/tables/cells/cell.dateTime.tsx +3 -7
- package/src/contexts/DateLocaleContext.tsx +106 -0
- package/src/contexts/__tests__/DateLocaleContext.spec.tsx +175 -0
- package/src/contexts/index.ts +1 -0
- package/src/date-locale/index.ts +12 -0
- package/src/features/account-deletion/components/AccountDeletionAdminTrigger.tsx +3 -4
- package/src/features/analytics/components/AnalyticsJourneyContainer.tsx +8 -8
- package/src/features/analytics/components/AnalyticsSessionsTable.tsx +4 -6
- package/src/features/auth/components/two-factor/PasskeyList.tsx +3 -3
- package/src/features/auth/components/two-factor/TotpAuthenticatorList.tsx +3 -3
- package/src/features/billing/components/utils/__tests__/billing-formatters.spec.ts +14 -6
- package/src/features/billing/components/utils/date.ts +5 -5
- package/src/features/billing/components/utils/format-options.ts +6 -4
- package/src/features/billing/components/utils/useBillingFormatOptions.ts +8 -2
- package/src/features/billing/stripe-usage/components/details/UsageSummaryCard.tsx +4 -12
- package/src/features/billing/stripe-usage/components/lists/UsageHistoryTable.tsx +4 -17
- package/src/features/blog/components/admin/BlogTranslationStatus.tsx +3 -2
- package/src/features/blog/components/public/BlogPostMeta.tsx +5 -4
- package/src/features/blog/components/public/__tests__/BlogList.spec.tsx +1 -2
- package/src/features/blog/components/public/__tests__/BlogPostView.spec.tsx +2 -3
- package/src/features/blog/hooks/useBlogPostTableStructure.tsx +4 -8
- package/src/features/email-automation/hooks/useEmailAutomationEnrollmentTableStructure.tsx +11 -5
- package/src/features/email-blast/components/containers/EmailBlastContainer.tsx +3 -3
- package/src/features/email-blast/hooks/useEmailBlastTableStructure.tsx +4 -4
- package/src/features/handbook/components/parts/HandbookIndexStatus.tsx +4 -3
- package/src/features/help/components/HelpArticleBody.tsx +4 -3
- package/src/features/notification/components/notifications/Notification.tsx +38 -7
- package/src/features/notification/contexts/NotificationContext.tsx +6 -3
- package/src/features/notification/hooks/useNotificationTableStructure.tsx +6 -5
- package/src/features/oauth/components/OAuthClientCard.tsx +8 -5
- package/src/features/oauth/components/OAuthClientDetail.tsx +3 -6
- package/src/features/tokenusage/lib/__tests__/formatters.spec.ts +19 -0
- package/src/features/tokenusage/lib/formatters.ts +11 -6
- package/src/features/waitlist/hooks/useWaitlistTableStructure.tsx +5 -5
- package/src/server/ServerSession.ts +3 -0
- package/src/server/__tests__/ServerSession.read.spec.ts +18 -1
- package/src/utils/__tests__/date-formatter.spec.ts +134 -10
- package/src/utils/__tests__/toast.spec.ts +39 -0
- package/src/utils/date-formatter.ts +200 -44
- package/src/utils/index.ts +11 -1
- package/src/utils/toast.ts +2 -0
- package/dist/BlockNoteEditor-MONT74RQ.js.map +0 -1
- package/dist/BlockNoteViewer-K2HBF3IP.js.map +0 -1
- package/dist/JsonApiRequest-KC6DOHKT.js +0 -26
- package/dist/chunk-7OIWOPM5.mjs.map +0 -1
- package/dist/chunk-BDWV4KYR.js.map +0 -1
- package/dist/chunk-HN7L6RRW.js.map +0 -1
- package/dist/chunk-N2BFT7KI.mjs.map +0 -1
- package/dist/chunk-OZADFYE7.mjs.map +0 -1
- package/dist/chunk-P7L6OFX5.js.map +0 -1
- package/dist/chunk-SO3YUCL6.js.map +0 -1
- package/dist/chunk-T6G2F2BK.mjs.map +0 -1
- package/dist/chunk-TNTCLVUR.js.map +0 -1
- package/dist/local-transport-MJPOKPTU.js +0 -15
- package/dist/write-through-7I3LA2WN.mjs +0 -15
- package/dist/write-through-HE2QSOVI.js +0 -15
- /package/dist/{JsonApiRequest-ADLBJ5RX.mjs.map → JsonApiRequest-WNPDS356.mjs.map} +0 -0
- /package/dist/{chunk-VNUT2D27.mjs.map → chunk-2PWYG2WJ.mjs.map} +0 -0
- /package/dist/{chunk-W4ML6D2X.mjs.map → chunk-3U7YJ73T.mjs.map} +0 -0
- /package/dist/{chunk-BE6UMM5X.mjs.map → chunk-47HNJQ7U.mjs.map} +0 -0
- /package/dist/{chunk-S7SPAC6X.mjs.map → chunk-73NKUBMP.mjs.map} +0 -0
- /package/dist/{chunk-YTDGYI62.mjs.map → chunk-DWPHHUMV.mjs.map} +0 -0
- /package/dist/{chunk-YMCL3JXZ.mjs.map → chunk-YPBIPE2B.mjs.map} +0 -0
- /package/dist/{local-transport-RVD4FZGA.mjs.map → date-locale/index.mjs.map} +0 -0
- /package/dist/{request-4AWGPIGH.mjs.map → local-transport-KWEUZ4GX.mjs.map} +0 -0
- /package/dist/{write-through-7I3LA2WN.mjs.map → request-6GAIWWTG.mjs.map} +0 -0
|
@@ -11,12 +11,53 @@ type FormatOption = "date" | "time" | "dateTime" | "timeSince" | "default";
|
|
|
11
11
|
* instant in time and the UTC shift is correct.
|
|
12
12
|
*/
|
|
13
13
|
export declare const formatLocalDate: (d: Date) => string;
|
|
14
|
+
export type DateFormatStyle = "date" | "dateMedium" | "dateLong" | "dateTime" | "dateTimeMedium" | "dateTimeLong" | "dateTimeSeconds" | "time" | "weekdayDateTime" | "weekdayDay" | "monthYear" | "monthYearLong" | "month" | "monthLong" | "dayMonth" | "weekday" | "weekdayLong";
|
|
14
15
|
/**
|
|
15
|
-
* The
|
|
16
|
-
* the
|
|
17
|
-
* other app locale ("it") is used as is.
|
|
16
|
+
* The option set behind each named style. No style pins `hour12` / `hourCycle`:
|
|
17
|
+
* the clock (12 or 24 hours) follows the locale.
|
|
18
18
|
*/
|
|
19
|
+
export declare const DATE_STYLE_OPTIONS: Record<DateFormatStyle, Intl.DateTimeFormatOptions>;
|
|
20
|
+
/** Public pages never show an all-numeric date: the month is spelled out. */
|
|
21
|
+
export declare const PUBLIC_STYLE_MAP: Partial<Record<DateFormatStyle, DateFormatStyle>>;
|
|
22
|
+
/**
|
|
23
|
+
* The locale every real-world date is formatted in.
|
|
24
|
+
*
|
|
25
|
+
* The first `Accept-Language` entry (quality order) whose language equals the
|
|
26
|
+
* app language's and that `Intl` supports; otherwise the app language. A
|
|
27
|
+
* malformed entry (`*`, an unparseable or zero quality, an unknown tag) is
|
|
28
|
+
* skipped, never thrown on.
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveDateLocale(params: {
|
|
31
|
+
appLocale: string;
|
|
32
|
+
acceptLanguage?: string;
|
|
33
|
+
}): string;
|
|
34
|
+
/**
|
|
35
|
+
* Formats a date in a named style. Returns "" for `undefined` or a value that
|
|
36
|
+
* does not parse. `isPublic` swaps the all-numeric styles for month-as-word.
|
|
37
|
+
*/
|
|
38
|
+
export declare function formatDateStyle(params: {
|
|
39
|
+
date: Date | string | undefined;
|
|
40
|
+
style: DateFormatStyle;
|
|
41
|
+
locale: string;
|
|
42
|
+
timeZone?: string;
|
|
43
|
+
isPublic?: boolean;
|
|
44
|
+
}): string;
|
|
45
|
+
/** "3 hours ago" / "3 ore fa", always numeric ("1 day ago", never "yesterday"). */
|
|
46
|
+
export declare function formatRelativeDate(params: {
|
|
47
|
+
date: Date | string;
|
|
48
|
+
locale: string;
|
|
49
|
+
now?: Date;
|
|
50
|
+
}): string;
|
|
51
|
+
/** True when the locale's clock is 12-hour (hour cycle h11 / h12). */
|
|
52
|
+
export declare function usesTwelveHourClock(locale: string): boolean;
|
|
53
|
+
/** The locale to format dates in for an app locale: the app locale itself, English when missing. */
|
|
19
54
|
export declare const dateFormatLocale: (appLocale?: string) => string;
|
|
20
|
-
|
|
55
|
+
/**
|
|
56
|
+
* @deprecated Use `formatDateStyle` (or `useDateFormatter().format`) and
|
|
57
|
+
* `formatRelativeDate` (or `useDateFormatter().relative`). Kept for other nja
|
|
58
|
+
* apps: same default locale and the same "date" / "time" / "dateTime" output.
|
|
59
|
+
* Pass `now` from render code; the `new Date()` fallback is for legacy callers.
|
|
60
|
+
*/
|
|
61
|
+
export declare const formatDate: (eventDate: Date, formatOption: FormatOption, locale?: string, now?: Date) => string;
|
|
21
62
|
export type { FormatOption };
|
|
22
63
|
//# sourceMappingURL=date-formatter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-formatter.d.ts","sourceRoot":"","sources":["../../src/utils/date-formatter.ts"],"names":[],"mappings":"AAAA,KAAK,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,CAAC;AAE3E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAAI,GAAG,IAAI,KAAG,MAKzC,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"date-formatter.d.ts","sourceRoot":"","sources":["../../src/utils/date-formatter.ts"],"names":[],"mappings":"AAAA,KAAK,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,CAAC;AAE3E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAAI,GAAG,IAAI,KAAG,MAKzC,CAAC;AAEF,MAAM,MAAM,eAAe,GACvB,MAAM,GACN,YAAY,GACZ,UAAU,GACV,UAAU,GACV,gBAAgB,GAChB,cAAc,GACd,iBAAiB,GACjB,MAAM,GACN,iBAAiB,GACjB,YAAY,GACZ,WAAW,GACX,eAAe,GACf,OAAO,GACP,WAAW,GACX,UAAU,GACV,SAAS,GACT,aAAa,CAAC;AAIlB;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,eAAe,EAAE,IAAI,CAAC,qBAAqB,CAkBlF,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,eAAe,CAAC,CAI9E,CAAC;AAyCF;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAqChG;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE;IACtC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,eAAe,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,MAAM,CAKT;AAED,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,IAAI,CAAA;CAAE,GAAG,MAAM,CAgBtG;AAED,sEAAsE;AACtE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAG3D;AAED,oGAAoG;AACpG,eAAO,MAAM,gBAAgB,GAAI,YAAY,MAAM,KAAG,MAA2B,CAAC;AAKlF;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GACrB,WAAW,IAAI,EACf,cAAc,YAAY,EAC1B,SAAQ,MAAgB,EACxB,MAAM,IAAI,KACT,MAqBF,CAAC;AAEF,YAAY,EAAE,YAAY,EAAE,CAAC"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export type { ClassValue } from "clsx";
|
|
|
2
2
|
export { cn } from "./cn";
|
|
3
3
|
export { composeRefs, useComposedRefs } from "./compose-refs";
|
|
4
4
|
export { useIsMobile, MOBILE_BREAKPOINT, VIEWPORT_COOKIE_NAME } from "./use-mobile";
|
|
5
|
-
export { dateFormatLocale, formatDate, formatLocalDate, type FormatOption } from "./date-formatter";
|
|
5
|
+
export { dateFormatLocale, formatDate, formatDateStyle, formatLocalDate, formatRelativeDate, resolveDateLocale, usesTwelveHourClock, type DateFormatStyle, type FormatOption, } from "./date-formatter";
|
|
6
6
|
export { exists } from "./exists";
|
|
7
7
|
export { getTableComponents, getTableOptions, TableOptions } from "./table-options";
|
|
8
8
|
export { entityObjectSchema, userObjectSchema, type EntityObject, type UserObject } from "./schemas";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGpF,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGpF,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGpF,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAErG,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,8BAA8B,GACpC,MAAM,sBAAsB,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,qCAAqC,CAAC;AACpD,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/utils/toast.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export type ToastOptions = {
|
|
|
6
6
|
id?: string;
|
|
7
7
|
onDismiss?: () => void;
|
|
8
8
|
action?: ExternalToast["action"];
|
|
9
|
+
/** sonner's second button, shown beside `action`. */
|
|
10
|
+
cancel?: ExternalToast["cancel"];
|
|
9
11
|
dismissible?: boolean;
|
|
10
12
|
};
|
|
11
13
|
/** Standard toast - neutral/white */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../src/utils/toast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5E,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,qCAAqC;AACrC,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,mBAEhE;AAED,oCAAoC;AACpC,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,mBAEhE;AAED,uBAAuB;AACvB,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,mBAErD;AAED,8DAA8D;AAC9D,wBAAgB,eAAe,CAC7B,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,KAAK,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC,EAC/F,OAAO,CAAC,EAAE;IACR,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB,mBAGF"}
|
|
1
|
+
{"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../src/utils/toast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5E,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,qDAAqD;IACrD,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,qCAAqC;AACrC,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,mBAEhE;AAED,oCAAoC;AACpC,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,mBAEhE;AAED,uBAAuB;AACvB,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,mBAErD;AAED,8DAA8D;AAC9D,wBAAgB,eAAe,CAC7B,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,KAAK,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC,EAC/F,OAAO,CAAC,EAAE;IACR,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB,mBAGF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
writeThrough
|
|
3
|
+
} from "./chunk-3U7YJ73T.mjs";
|
|
4
|
+
import "./chunk-DWPHHUMV.mjs";
|
|
5
|
+
import "./chunk-4RPGFQBA.mjs";
|
|
6
|
+
import "./chunk-47HNJQ7U.mjs";
|
|
7
|
+
import "./chunk-73NKUBMP.mjs";
|
|
8
|
+
import "./chunk-4ZJIUTIV.mjs";
|
|
9
|
+
import "./chunk-YPBIPE2B.mjs";
|
|
10
|
+
import "./chunk-AUXK7QSA.mjs";
|
|
11
|
+
import "./chunk-PAWJFY3S.mjs";
|
|
12
|
+
export {
|
|
13
|
+
writeThrough
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=write-through-KNRI5L4V.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
var _chunkPQQFOONGjs = require('./chunk-PQQFOONG.js');
|
|
4
|
+
require('./chunk-FBHUUPRV.js');
|
|
5
|
+
require('./chunk-6RCZ64BQ.js');
|
|
6
|
+
require('./chunk-3VNDFKT7.js');
|
|
7
|
+
require('./chunk-5WM72MLE.js');
|
|
8
|
+
require('./chunk-WUNSG3IN.js');
|
|
9
|
+
require('./chunk-LNO2JLU3.js');
|
|
10
|
+
require('./chunk-LXKSUWAV.js');
|
|
11
|
+
require('./chunk-7QVYU63E.js');
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
exports.writeThrough = _chunkPQQFOONGjs.writeThrough;
|
|
15
|
+
//# sourceMappingURL=write-through-MYHQ6GJU.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/write-through-
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/write-through-MYHQ6GJU.js"],"names":[],"mappings":"AAAA;AACE;AACF,sDAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B,+BAA4B;AAC5B;AACE;AACF,qDAAC","file":"/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/write-through-MYHQ6GJU.js"}
|
package/messages/en.json
CHANGED
package/messages/it.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carlonicora/nextjs-jsonapi",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.26.0",
|
|
4
4
|
"description": "Next.js JSON:API client with server/client support and caching",
|
|
5
5
|
"author": "Carlo Nicora",
|
|
6
6
|
"license": "GPL-3.0-or-later",
|
|
@@ -53,6 +53,11 @@
|
|
|
53
53
|
"import": "./dist/contexts/index.mjs",
|
|
54
54
|
"require": "./dist/contexts/index.js"
|
|
55
55
|
},
|
|
56
|
+
"./date-locale": {
|
|
57
|
+
"types": "./dist/date-locale/index.d.ts",
|
|
58
|
+
"import": "./dist/date-locale/index.mjs",
|
|
59
|
+
"require": "./dist/date-locale/index.js"
|
|
60
|
+
},
|
|
56
61
|
"./contexts/styles.css": "./dist/contexts/index.css",
|
|
57
62
|
"./blocknote/server": {
|
|
58
63
|
"types": "./dist/components/editors/server-entry.d.ts",
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
import { isValid, parse } from "date-fns";
|
|
4
4
|
import { Calendar as CalendarIcon, CircleXIcon } from "lucide-react";
|
|
5
5
|
import { ReactElement, useMemo, useState } from "react";
|
|
6
|
-
import {
|
|
6
|
+
import { useDateLocale } from "../../contexts/DateLocaleContext";
|
|
7
|
+
import { useI18nDateFnsLocale } from "../../i18n";
|
|
7
8
|
import {
|
|
8
9
|
Calendar,
|
|
9
10
|
Input,
|
|
@@ -48,8 +49,9 @@ export const DatePickerPopover = ({
|
|
|
48
49
|
align = "start",
|
|
49
50
|
className,
|
|
50
51
|
}: DatePickerPopoverProps) => {
|
|
51
|
-
const locale =
|
|
52
|
+
const { locale } = useDateLocale();
|
|
52
53
|
const dateFnsLocale = useI18nDateFnsLocale();
|
|
54
|
+
const weekStartsOn = (dateFnsLocale?.options?.weekStartsOn ?? 1) as 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
53
55
|
const [isOpen, setIsOpen] = useState(false);
|
|
54
56
|
const [displayMonth, setDisplayMonth] = useState<Date>(() => value || new Date());
|
|
55
57
|
|
|
@@ -239,7 +241,7 @@ export const DatePickerPopover = ({
|
|
|
239
241
|
onSelect={handleCalendarSelect}
|
|
240
242
|
disabled={(date) => (minDate && date < minDate ? true : false)}
|
|
241
243
|
locale={dateFnsLocale}
|
|
242
|
-
weekStartsOn={
|
|
244
|
+
weekStartsOn={weekStartsOn}
|
|
243
245
|
month={displayMonth}
|
|
244
246
|
onMonthChange={setDisplayMonth}
|
|
245
247
|
/>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { format } from "date-fns";
|
|
4
3
|
import { CalendarIcon } from "lucide-react";
|
|
5
4
|
import { useTranslations } from "next-intl";
|
|
6
5
|
import { useEffect, useState } from "react";
|
|
7
6
|
import { DateRange } from "react-day-picker";
|
|
7
|
+
import { useDateFormatter } from "../../contexts/DateLocaleContext";
|
|
8
8
|
import { useI18nDateFnsLocale } from "../../i18n";
|
|
9
9
|
import { Button, Calendar, Popover, PopoverContent, PopoverTrigger } from "../../shadcnui";
|
|
10
10
|
import { cn } from "../../utils";
|
|
@@ -50,7 +50,9 @@ type DateRangeSelectorProps = {
|
|
|
50
50
|
|
|
51
51
|
export function DateRangeSelector({ onDateChange, avoidSettingDates, showPreviousMonth }: DateRangeSelectorProps) {
|
|
52
52
|
const t = useTranslations();
|
|
53
|
+
const { format } = useDateFormatter();
|
|
53
54
|
const dateFnsLocale = useI18nDateFnsLocale();
|
|
55
|
+
const weekStartsOn = (dateFnsLocale?.options?.weekStartsOn ?? 1) as 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
54
56
|
const [date, setDate] = useState<DateRange | undefined>(
|
|
55
57
|
avoidSettingDates
|
|
56
58
|
? undefined
|
|
@@ -100,11 +102,10 @@ export function DateRangeSelector({ onDateChange, avoidSettingDates, showPreviou
|
|
|
100
102
|
{date?.from ? (
|
|
101
103
|
date.to ? (
|
|
102
104
|
<>
|
|
103
|
-
{format(date.from, "
|
|
104
|
-
{format(date.to, "d MMM yyyy", { locale: dateFnsLocale })}
|
|
105
|
+
{format(date.from, "dateMedium")} - {format(date.to, "dateMedium")}
|
|
105
106
|
</>
|
|
106
107
|
) : (
|
|
107
|
-
format(date.from, "
|
|
108
|
+
format(date.from, "dateMedium")
|
|
108
109
|
)
|
|
109
110
|
) : (
|
|
110
111
|
<span>{t("ui.labels.pick_a_date")}</span>
|
|
@@ -130,11 +131,10 @@ export function DateRangeSelector({ onDateChange, avoidSettingDates, showPreviou
|
|
|
130
131
|
{date?.from ? (
|
|
131
132
|
date.to ? (
|
|
132
133
|
<>
|
|
133
|
-
{format(date.from, "
|
|
134
|
-
{format(date.to, "d MMM yyyy", { locale: dateFnsLocale })}
|
|
134
|
+
{format(date.from, "dateMedium")} - {format(date.to, "dateMedium")}
|
|
135
135
|
</>
|
|
136
136
|
) : (
|
|
137
|
-
format(date.from, "
|
|
137
|
+
format(date.from, "dateMedium")
|
|
138
138
|
)
|
|
139
139
|
) : (
|
|
140
140
|
<span>{t("ui.labels.pick_a_date")}</span>
|
|
@@ -151,6 +151,8 @@ export function DateRangeSelector({ onDateChange, avoidSettingDates, showPreviou
|
|
|
151
151
|
selected={date}
|
|
152
152
|
onSelect={handleSelect}
|
|
153
153
|
numberOfMonths={2}
|
|
154
|
+
locale={dateFnsLocale}
|
|
155
|
+
weekStartsOn={weekStartsOn}
|
|
154
156
|
/>
|
|
155
157
|
<Button
|
|
156
158
|
variant="secondary"
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
import { isValid, parse } from "date-fns";
|
|
4
4
|
import { Calendar as CalendarIcon, CircleXIcon } from "lucide-react";
|
|
5
5
|
import { useMemo, useState } from "react";
|
|
6
|
-
import {
|
|
6
|
+
import { useDateLocale } from "../../contexts/DateLocaleContext";
|
|
7
|
+
import { useI18nDateFnsLocale, useI18nTranslations } from "../../i18n";
|
|
7
8
|
import {
|
|
8
9
|
Button,
|
|
9
10
|
Calendar,
|
|
@@ -42,8 +43,9 @@ export function FormDate({
|
|
|
42
43
|
futureYears?: number;
|
|
43
44
|
}) {
|
|
44
45
|
const t = useI18nTranslations();
|
|
45
|
-
const locale =
|
|
46
|
+
const { locale } = useDateLocale();
|
|
46
47
|
const dateFnsLocale = useI18nDateFnsLocale();
|
|
48
|
+
const weekStartsOn = (dateFnsLocale?.options?.weekStartsOn ?? 1) as 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
47
49
|
const [open, setOpen] = useState<boolean>(false);
|
|
48
50
|
const [displayMonth, setDisplayMonth] = useState<Date>(() => {
|
|
49
51
|
const currentValue = form.getValues(id);
|
|
@@ -162,7 +164,7 @@ export function FormDate({
|
|
|
162
164
|
}}
|
|
163
165
|
disabled={(date) => (minDate && date < minDate ? true : false)}
|
|
164
166
|
locale={dateFnsLocale}
|
|
165
|
-
weekStartsOn={
|
|
167
|
+
weekStartsOn={weekStartsOn}
|
|
166
168
|
month={displayMonth}
|
|
167
169
|
onMonthChange={setDisplayMonth}
|
|
168
170
|
startMonth={new Date(1900, 0)}
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { Calendar as CalendarIcon, CircleXIcon } from "lucide-react";
|
|
4
4
|
import { useMemo, useState } from "react";
|
|
5
|
-
import {
|
|
5
|
+
import { useDateFormatter } from "../../contexts/DateLocaleContext";
|
|
6
|
+
import { useI18nDateFnsLocale, useI18nTranslations } from "../../i18n";
|
|
6
7
|
import {
|
|
7
8
|
Button,
|
|
8
9
|
Calendar,
|
|
@@ -18,6 +19,7 @@ import {
|
|
|
18
19
|
} from "../../shadcnui";
|
|
19
20
|
import { cn } from "../../utils";
|
|
20
21
|
import { FormFieldWrapper } from "./FormFieldWrapper";
|
|
22
|
+
import { DayPeriod, dayPeriodLabels, from24Hour, to24Hour } from "./time-cycle";
|
|
21
23
|
|
|
22
24
|
// Unwrapped rounding: setMinutes(60) carries into the hour, so 10:58 becomes 11:00
|
|
23
25
|
function snapToFiveMinutes(date: Date): Date {
|
|
@@ -57,30 +59,20 @@ export function FormDateTime({
|
|
|
57
59
|
}) {
|
|
58
60
|
const [open, setOpen] = useState<boolean>(false);
|
|
59
61
|
const t = useI18nTranslations();
|
|
60
|
-
const locale =
|
|
62
|
+
const { format, locale, twelveHourClock } = useDateFormatter();
|
|
61
63
|
const dateFnsLocale = useI18nDateFnsLocale();
|
|
64
|
+
const weekStartsOn = (dateFnsLocale?.options?.weekStartsOn ?? 1) as 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
62
65
|
|
|
63
66
|
const [displayMonth, setDisplayMonth] = useState<Date>(() => {
|
|
64
67
|
const currentValue = form.getValues(id);
|
|
65
68
|
return currentValue || defaultMonth || reference?.date || new Date();
|
|
66
69
|
});
|
|
67
70
|
|
|
68
|
-
//
|
|
69
|
-
const
|
|
70
|
-
() =>
|
|
71
|
-
new Intl.DateTimeFormat(locale, {
|
|
72
|
-
year: "numeric",
|
|
73
|
-
month: "long",
|
|
74
|
-
day: "numeric",
|
|
75
|
-
hour: "2-digit",
|
|
76
|
-
minute: "2-digit",
|
|
77
|
-
hour12: false,
|
|
78
|
-
}),
|
|
79
|
-
[locale],
|
|
80
|
-
);
|
|
71
|
+
// Format date-time for display; the clock (12/24-hour) follows the resolved locale
|
|
72
|
+
const formatDateTime = (date: Date): string => format(date, "dateTimeLong");
|
|
81
73
|
|
|
82
|
-
//
|
|
83
|
-
const
|
|
74
|
+
// AM/PM labels from Intl, only needed on a 12-hour locale
|
|
75
|
+
const periodLabels = useMemo(() => dayPeriodLabels(locale), [locale]);
|
|
84
76
|
|
|
85
77
|
// An empty field starts its time selects at the reference "now" when one is given
|
|
86
78
|
// Snapped as an instant (not by wrapping minutes) so 10:58 starts at 11:00
|
|
@@ -100,13 +92,27 @@ export function FormDateTime({
|
|
|
100
92
|
marked: "[&>button]:underline [&>button]:decoration-2 [&>button]:underline-offset-4",
|
|
101
93
|
};
|
|
102
94
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
95
|
+
// 12-hour locales list 1–12 (plus an AM/PM select); 24-hour locales list 0–23
|
|
96
|
+
const hoursOptions = twelveHourClock
|
|
97
|
+
? Array.from({ length: 12 }, (_, i) => {
|
|
98
|
+
const hour = i + 1;
|
|
99
|
+
return {
|
|
100
|
+
value: hour,
|
|
101
|
+
label: hour.toString(),
|
|
102
|
+
};
|
|
103
|
+
})
|
|
104
|
+
: Array.from({ length: 24 }, (_, i) => {
|
|
105
|
+
const hour = i;
|
|
106
|
+
return {
|
|
107
|
+
value: hour,
|
|
108
|
+
label: hour.toString().padStart(2, "0"),
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const periodOptions: { value: DayPeriod; label: string }[] = [
|
|
113
|
+
{ value: "am", label: periodLabels.am },
|
|
114
|
+
{ value: "pm", label: periodLabels.pm },
|
|
115
|
+
];
|
|
110
116
|
|
|
111
117
|
const minutesOptions = Array.from({ length: 12 }, (_, i) => {
|
|
112
118
|
const minute = i * 5;
|
|
@@ -118,6 +124,7 @@ export function FormDateTime({
|
|
|
118
124
|
|
|
119
125
|
const hoursItems = Object.fromEntries(hoursOptions.map((option) => [String(option.value), option.label]));
|
|
120
126
|
const minutesItems = Object.fromEntries(minutesOptions.map((option) => [String(option.value), option.label]));
|
|
127
|
+
const periodItems = Object.fromEntries(periodOptions.map((option) => [option.value, option.label]));
|
|
121
128
|
|
|
122
129
|
function roundToNearestFiveMinutes(minutes: number): number {
|
|
123
130
|
return (Math.round(minutes / 5) * 5) % 60;
|
|
@@ -133,6 +140,11 @@ export function FormDateTime({
|
|
|
133
140
|
setSelectedMinutes(referenceDate.getMinutes());
|
|
134
141
|
};
|
|
135
142
|
|
|
143
|
+
// The time the selects show: the field's own time, else the pending selection (0–23 / 0–55)
|
|
144
|
+
const currentHours = (value: Date | undefined): number => (value ? new Date(value).getHours() : selectedHours);
|
|
145
|
+
const currentMinutes = (value: Date | undefined): number =>
|
|
146
|
+
value ? roundToNearestFiveMinutes(new Date(value).getMinutes()) : selectedMinutes;
|
|
147
|
+
|
|
136
148
|
const handleTimeChange = (hours: number, minutes: number) => {
|
|
137
149
|
const currentDate = form.getValues(id);
|
|
138
150
|
if (currentDate) {
|
|
@@ -205,7 +217,7 @@ export function FormDateTime({
|
|
|
205
217
|
}}
|
|
206
218
|
disabled={(date) => (minDate && date < minDate ? true : false)}
|
|
207
219
|
locale={dateFnsLocale}
|
|
208
|
-
weekStartsOn={
|
|
220
|
+
weekStartsOn={weekStartsOn}
|
|
209
221
|
startMonth={new Date(1900, 0)}
|
|
210
222
|
endMonth={new Date(new Date().getFullYear() + 10, 11)}
|
|
211
223
|
modifiers={dayModifiers}
|
|
@@ -228,20 +240,20 @@ export function FormDateTime({
|
|
|
228
240
|
<Label htmlFor="hours-select">{t(`common.hours`)}</Label>
|
|
229
241
|
<Select
|
|
230
242
|
items={hoursItems}
|
|
231
|
-
value={String(
|
|
243
|
+
value={String(
|
|
244
|
+
twelveHourClock ? from24Hour(currentHours(field.value)).hour12 : currentHours(field.value),
|
|
245
|
+
)}
|
|
232
246
|
onValueChange={(value) => {
|
|
233
247
|
if (!value) return;
|
|
234
|
-
const
|
|
248
|
+
const picked = parseInt(value);
|
|
249
|
+
const hours = twelveHourClock
|
|
250
|
+
? to24Hour(picked, from24Hour(currentHours(field.value)).period)
|
|
251
|
+
: picked;
|
|
235
252
|
setSelectedHours(hours);
|
|
236
|
-
handleTimeChange(
|
|
237
|
-
hours,
|
|
238
|
-
field.value
|
|
239
|
-
? roundToNearestFiveMinutes(new Date(field.value).getMinutes())
|
|
240
|
-
: selectedMinutes,
|
|
241
|
-
);
|
|
253
|
+
handleTimeChange(hours, currentMinutes(field.value));
|
|
242
254
|
}}
|
|
243
255
|
>
|
|
244
|
-
<SelectTrigger id="hours-select" className="w-[70px]">
|
|
256
|
+
<SelectTrigger id="hours-select" data-testid="form-datetime-hours" className="w-[70px]">
|
|
245
257
|
<SelectValue />
|
|
246
258
|
</SelectTrigger>
|
|
247
259
|
<SelectContent>
|
|
@@ -258,17 +270,15 @@ export function FormDateTime({
|
|
|
258
270
|
<Label htmlFor="minutes-select">{t(`common.minutes`)}</Label>
|
|
259
271
|
<Select
|
|
260
272
|
items={minutesItems}
|
|
261
|
-
value={String(
|
|
262
|
-
field.value ? roundToNearestFiveMinutes(new Date(field.value).getMinutes()) : selectedMinutes,
|
|
263
|
-
)}
|
|
273
|
+
value={String(currentMinutes(field.value))}
|
|
264
274
|
onValueChange={(value) => {
|
|
265
275
|
if (!value) return;
|
|
266
276
|
const minutes = parseInt(value);
|
|
267
277
|
setSelectedMinutes(minutes);
|
|
268
|
-
handleTimeChange(
|
|
278
|
+
handleTimeChange(currentHours(field.value), minutes);
|
|
269
279
|
}}
|
|
270
280
|
>
|
|
271
|
-
<SelectTrigger id="minutes-select" className="w-[70px]">
|
|
281
|
+
<SelectTrigger id="minutes-select" data-testid="form-datetime-minutes" className="w-[70px]">
|
|
272
282
|
<SelectValue />
|
|
273
283
|
</SelectTrigger>
|
|
274
284
|
<SelectContent>
|
|
@@ -280,6 +290,32 @@ export function FormDateTime({
|
|
|
280
290
|
</SelectContent>
|
|
281
291
|
</Select>
|
|
282
292
|
</div>
|
|
293
|
+
{twelveHourClock && (
|
|
294
|
+
<div className="flex flex-col space-y-2">
|
|
295
|
+
<Label htmlFor="period-select">{t(`common.dayPeriod`)}</Label>
|
|
296
|
+
<Select
|
|
297
|
+
items={periodItems}
|
|
298
|
+
value={from24Hour(currentHours(field.value)).period}
|
|
299
|
+
onValueChange={(value) => {
|
|
300
|
+
if (!value) return;
|
|
301
|
+
const hours = to24Hour(from24Hour(currentHours(field.value)).hour12, value as DayPeriod);
|
|
302
|
+
setSelectedHours(hours);
|
|
303
|
+
handleTimeChange(hours, currentMinutes(field.value));
|
|
304
|
+
}}
|
|
305
|
+
>
|
|
306
|
+
<SelectTrigger id="period-select" data-testid="form-datetime-period" className="w-[70px]">
|
|
307
|
+
<SelectValue />
|
|
308
|
+
</SelectTrigger>
|
|
309
|
+
<SelectContent>
|
|
310
|
+
{periodOptions.map((option) => (
|
|
311
|
+
<SelectItem key={option.value} value={option.value}>
|
|
312
|
+
{option.label}
|
|
313
|
+
</SelectItem>
|
|
314
|
+
))}
|
|
315
|
+
</SelectContent>
|
|
316
|
+
</Select>
|
|
317
|
+
</div>
|
|
318
|
+
)}
|
|
283
319
|
</div>
|
|
284
320
|
<div className="mt-2 flex flex-row gap-x-2">
|
|
285
321
|
{allowEmpty !== false && (
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { dayPeriodLabels, from24Hour, to24Hour } from "../time-cycle";
|
|
3
|
+
|
|
4
|
+
describe("to24Hour / from24Hour round-trip", () => {
|
|
5
|
+
it("maps 12-hour values around midnight and noon", () => {
|
|
6
|
+
expect(to24Hour(12, "am")).toBe(0);
|
|
7
|
+
expect(to24Hour(12, "pm")).toBe(12);
|
|
8
|
+
expect(to24Hour(11, "pm")).toBe(23);
|
|
9
|
+
expect(to24Hour(1, "am")).toBe(1);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("maps 24-hour values to 12-hour values", () => {
|
|
13
|
+
expect(from24Hour(0)).toEqual({ hour12: 12, period: "am" });
|
|
14
|
+
expect(from24Hour(13)).toEqual({ hour12: 1, period: "pm" });
|
|
15
|
+
expect(from24Hour(12)).toEqual({ hour12: 12, period: "pm" });
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("round-trips every hour of the day", () => {
|
|
19
|
+
for (let hour = 0; hour < 24; hour++) {
|
|
20
|
+
const { hour12, period } = from24Hour(hour);
|
|
21
|
+
expect(to24Hour(hour12, period)).toBe(hour);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("dayPeriodLabels", () => {
|
|
27
|
+
it("reads the en-US labels from Intl", () => {
|
|
28
|
+
expect(dayPeriodLabels("en-US")).toEqual({ am: "AM", pm: "PM" });
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("returns two non-empty, different labels for it", () => {
|
|
32
|
+
const labels = dayPeriodLabels("it");
|
|
33
|
+
expect(labels.am.length).toBeGreaterThan(0);
|
|
34
|
+
expect(labels.pm.length).toBeGreaterThan(0);
|
|
35
|
+
expect(labels.am).not.toBe(labels.pm);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type DayPeriod = "am" | "pm";
|
|
2
|
+
|
|
3
|
+
/** 12-hour clock value + period → 0–23 (12 am → 0, 12 pm → 12). */
|
|
4
|
+
export function to24Hour(hour12: number, period: DayPeriod): number {
|
|
5
|
+
const base = hour12 % 12;
|
|
6
|
+
return period === "pm" ? base + 12 : base;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** 0–23 → 12-hour clock value + period (0 → 12 am, 12 → 12 pm). */
|
|
10
|
+
export function from24Hour(hour24: number): { hour12: number; period: DayPeriod } {
|
|
11
|
+
const period: DayPeriod = hour24 >= 12 ? "pm" : "am";
|
|
12
|
+
const hour12 = hour24 % 12 === 0 ? 12 : hour24 % 12;
|
|
13
|
+
return { hour12, period };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function dayPeriodOf(formatter: Intl.DateTimeFormat, date: Date): string {
|
|
17
|
+
return formatter.formatToParts(date).find((part) => part.type === "dayPeriod")?.value ?? "";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** The locale's own AM/PM labels, read from Intl (never hard-coded). */
|
|
21
|
+
export function dayPeriodLabels(locale: string): { am: string; pm: string } {
|
|
22
|
+
const formatter = new Intl.DateTimeFormat(locale, { hour: "numeric", hourCycle: "h12" });
|
|
23
|
+
return {
|
|
24
|
+
am: dayPeriodOf(formatter, new Date(2000, 0, 1, 1, 0)),
|
|
25
|
+
pm: dayPeriodOf(formatter, new Date(2000, 0, 1, 13, 0)),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { ColumnDef } from "@tanstack/react-table";
|
|
2
|
-
import {
|
|
2
|
+
import { useDateFormatter } from "../../../contexts/DateLocaleContext";
|
|
3
3
|
|
|
4
4
|
function DateCell({ date }: { date: Date }) {
|
|
5
|
-
const
|
|
6
|
-
return (
|
|
7
|
-
<span className="text-muted-foreground text-xs">{date.toLocaleDateString(locale, { dateStyle: "medium" })}</span>
|
|
8
|
-
);
|
|
5
|
+
const { format } = useDateFormatter();
|
|
6
|
+
return <span className="text-muted-foreground text-xs">{format(date, "dateMedium")}</span>;
|
|
9
7
|
}
|
|
10
8
|
|
|
11
9
|
export const cellDate = (params: { name: string; title: string }): ColumnDef<any> => {
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import { ColumnDef } from "@tanstack/react-table";
|
|
2
|
-
import {
|
|
2
|
+
import { useDateFormatter } from "../../../contexts/DateLocaleContext";
|
|
3
3
|
|
|
4
4
|
function DateTimeCell({ date }: { date: Date }) {
|
|
5
|
-
const
|
|
6
|
-
return (
|
|
7
|
-
<span className="text-muted-foreground text-xs">
|
|
8
|
-
{date.toLocaleString(locale, { dateStyle: "medium", timeStyle: "short", hour12: false })}
|
|
9
|
-
</span>
|
|
10
|
-
);
|
|
5
|
+
const { format } = useDateFormatter();
|
|
6
|
+
return <span className="text-muted-foreground text-xs">{format(date, "dateTimeMedium")}</span>;
|
|
11
7
|
}
|
|
12
8
|
|
|
13
9
|
export const cellDateTime = (params: { name: string; title: string }): ColumnDef<any> => {
|