@getmicdrop/svelte-components 5.3.12 → 5.3.13

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 (248) hide show
  1. package/dist/calendar/AboutShow/AboutShow.svelte +172 -172
  2. package/dist/calendar/Calendar/MiniMonthCalendar.svelte +782 -782
  3. package/dist/calendar/FAQs/FAQs.svelte +75 -75
  4. package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte +126 -126
  5. package/dist/calendar/OrderSummary/OrderSummary.svelte +367 -367
  6. package/dist/calendar/PublicCard/PublicCard.svelte +145 -145
  7. package/dist/calendar/ShowCard/ShowCard.svelte +157 -157
  8. package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte +61 -61
  9. package/dist/components/Layout/Grid.svelte +109 -109
  10. package/dist/components/Layout/Section.svelte +80 -80
  11. package/dist/components/Layout/Sidebar.svelte +108 -108
  12. package/dist/components/Layout/Stack.svelte +90 -90
  13. package/dist/constants/formOptions.js +26 -26
  14. package/dist/constants/validation.js +91 -91
  15. package/dist/constants/validation.spec.js +64 -64
  16. package/dist/datetime/__tests__/format.test.d.ts +2 -0
  17. package/dist/datetime/__tests__/format.test.d.ts.map +1 -0
  18. package/dist/datetime/__tests__/format.test.js +268 -0
  19. package/dist/datetime/__tests__/integration.test.d.ts +2 -0
  20. package/dist/datetime/__tests__/integration.test.d.ts.map +1 -0
  21. package/dist/datetime/__tests__/integration.test.js +243 -0
  22. package/dist/datetime/__tests__/parse.test.d.ts +2 -0
  23. package/dist/datetime/__tests__/parse.test.d.ts.map +1 -0
  24. package/dist/datetime/__tests__/parse.test.js +261 -0
  25. package/dist/datetime/__tests__/timezone.test.d.ts +2 -0
  26. package/dist/datetime/__tests__/timezone.test.d.ts.map +1 -0
  27. package/dist/datetime/__tests__/timezone.test.js +214 -0
  28. package/dist/datetime/constants.d.ts +133 -0
  29. package/dist/datetime/constants.d.ts.map +1 -0
  30. package/dist/datetime/constants.js +112 -0
  31. package/dist/datetime/format.d.ts +158 -0
  32. package/dist/datetime/format.d.ts.map +1 -0
  33. package/dist/datetime/format.js +315 -0
  34. package/dist/datetime/index.d.ts +42 -0
  35. package/dist/datetime/index.d.ts.map +1 -0
  36. package/dist/datetime/index.js +44 -0
  37. package/dist/datetime/parse.d.ts +149 -0
  38. package/dist/datetime/parse.d.ts.map +1 -0
  39. package/dist/datetime/parse.js +276 -0
  40. package/dist/datetime/timezone.d.ts +95 -0
  41. package/dist/datetime/timezone.d.ts.map +1 -0
  42. package/dist/datetime/timezone.js +241 -0
  43. package/dist/datetime/types.d.ts +105 -0
  44. package/dist/datetime/types.d.ts.map +1 -0
  45. package/dist/datetime/types.js +31 -0
  46. package/dist/index.d.ts +10 -0
  47. package/dist/index.js +232 -218
  48. package/dist/patterns/data/DataGrid.svelte +45 -45
  49. package/dist/patterns/data/DataList.svelte +24 -24
  50. package/dist/patterns/data/DataTable.svelte +40 -40
  51. package/dist/patterns/forms/FormActions.spec.js +88 -88
  52. package/dist/patterns/forms/FormActions.stories.svelte +97 -97
  53. package/dist/patterns/forms/FormActions.svelte +46 -46
  54. package/dist/patterns/forms/FormGrid.svelte +33 -33
  55. package/dist/patterns/forms/FormSection.svelte +32 -32
  56. package/dist/patterns/forms/FormValidationSummary.spec.js +203 -203
  57. package/dist/patterns/forms/FormValidationSummary.stories.svelte +97 -97
  58. package/dist/patterns/forms/FormValidationSummary.svelte +67 -67
  59. package/dist/patterns/layout/Grid.svelte +35 -35
  60. package/dist/patterns/layout/Sidebar.svelte +39 -39
  61. package/dist/patterns/layout/Stack.svelte +45 -45
  62. package/dist/patterns/navigation/BottomNav.spec.js +130 -130
  63. package/dist/patterns/navigation/BottomNav.stories.svelte +117 -117
  64. package/dist/patterns/navigation/BottomNav.svelte +54 -54
  65. package/dist/patterns/navigation/Header.spec.js +203 -203
  66. package/dist/patterns/navigation/Header.stories.svelte +77 -77
  67. package/dist/patterns/navigation/Header.svelte +240 -240
  68. package/dist/patterns/page/PageHeader.svelte +36 -36
  69. package/dist/patterns/page/PageLayout.svelte +40 -40
  70. package/dist/patterns/page/PageLoader.spec.js +54 -54
  71. package/dist/patterns/page/PageLoader.stories.svelte +137 -137
  72. package/dist/patterns/page/PageLoader.svelte +41 -41
  73. package/dist/patterns/page/SectionHeader.svelte +41 -41
  74. package/dist/presets/badges.js +112 -112
  75. package/dist/presets/buttons.js +76 -76
  76. package/dist/presets/index.js +9 -9
  77. package/dist/primitives/Accordion/Accordion.stories.svelte +75 -75
  78. package/dist/primitives/Accordion/Accordion.svelte +61 -61
  79. package/dist/primitives/Accordion/AccordionItem.svelte +95 -95
  80. package/dist/primitives/Alert/Alert.spec.js +170 -170
  81. package/dist/primitives/Alert/Alert.stories.svelte +88 -88
  82. package/dist/primitives/Alert/Alert.svelte +65 -65
  83. package/dist/primitives/Avatar/Avatar.stories.svelte +94 -94
  84. package/dist/primitives/Avatar/Avatar.svelte +66 -66
  85. package/dist/primitives/Badges/Badge.spec.js +103 -103
  86. package/dist/primitives/Badges/Badge.stories.svelte +86 -86
  87. package/dist/primitives/Badges/Badge.svelte +142 -142
  88. package/dist/primitives/BottomSheet/BottomSheet.spec.js +127 -127
  89. package/dist/primitives/BottomSheet/BottomSheet.stories.svelte +83 -83
  90. package/dist/primitives/BottomSheet/BottomSheet.svelte +100 -100
  91. package/dist/primitives/Breadcrumb/Breadcrumb.spec.js +120 -120
  92. package/dist/primitives/Breadcrumb/Breadcrumb.stories.svelte +23 -23
  93. package/dist/primitives/Breadcrumb/Breadcrumb.svelte +89 -89
  94. package/dist/primitives/Button/Button.spec.js +211 -211
  95. package/dist/primitives/Button/Button.stories.svelte +76 -76
  96. package/dist/primitives/Button/Button.svelte +301 -301
  97. package/dist/primitives/Button/ButtonSaveDemo.spec.js +48 -48
  98. package/dist/primitives/Button/ButtonSaveDemo.svelte +25 -25
  99. package/dist/primitives/Button/ButtonVariantShowcase.svelte +129 -129
  100. package/dist/primitives/Card.spec.js +49 -49
  101. package/dist/primitives/Card.stories.svelte +22 -22
  102. package/dist/primitives/Card.svelte +28 -28
  103. package/dist/primitives/Checkbox/Checkbox.stories.svelte +84 -84
  104. package/dist/primitives/Checkbox/Checkbox.svelte +88 -88
  105. package/dist/primitives/DarkModeToggle.spec.js +357 -357
  106. package/dist/primitives/DarkModeToggle.stories.svelte +57 -57
  107. package/dist/primitives/DarkModeToggle.svelte +136 -136
  108. package/dist/primitives/Drawer/Drawer.stories.svelte +100 -100
  109. package/dist/primitives/Drawer/Drawer.svelte +214 -214
  110. package/dist/primitives/Dropdown/Dropdown.stories.svelte +137 -137
  111. package/dist/primitives/Dropdown/Dropdown.svelte +148 -148
  112. package/dist/primitives/Dropdown/DropdownItem.svelte +80 -80
  113. package/dist/primitives/Icons/ArrowLeft.svelte +20 -20
  114. package/dist/primitives/Icons/ArrowRight.svelte +20 -20
  115. package/dist/primitives/Icons/Availability.svelte +26 -26
  116. package/dist/primitives/Icons/Back.svelte +26 -26
  117. package/dist/primitives/Icons/CheckCircle.svelte +18 -18
  118. package/dist/primitives/Icons/CheckCircleOutline.svelte +27 -27
  119. package/dist/primitives/Icons/ChevronLeft.svelte +16 -16
  120. package/dist/primitives/Icons/ChevronRight.svelte +16 -16
  121. package/dist/primitives/Icons/Copy.svelte +27 -27
  122. package/dist/primitives/Icons/Cross.svelte +17 -17
  123. package/dist/primitives/Icons/DownArrow.svelte +20 -20
  124. package/dist/primitives/Icons/ErrorCircle.svelte +18 -18
  125. package/dist/primitives/Icons/FacebookIcon.svelte +13 -13
  126. package/dist/primitives/Icons/Home.svelte +27 -27
  127. package/dist/primitives/Icons/Icon.spec.js +175 -175
  128. package/dist/primitives/Icons/Icon.stories.svelte +100 -100
  129. package/dist/primitives/Icons/Icon.svelte +63 -63
  130. package/dist/primitives/Icons/IconGallery.stories.svelte +235 -235
  131. package/dist/primitives/Icons/ImageOutline.svelte +19 -19
  132. package/dist/primitives/Icons/Info.svelte +19 -19
  133. package/dist/primitives/Icons/InstagramIcon.svelte +19 -19
  134. package/dist/primitives/Icons/LogoInstagram.svelte +15 -15
  135. package/dist/primitives/Icons/Message.svelte +27 -27
  136. package/dist/primitives/Icons/MoonIcon.svelte +16 -16
  137. package/dist/primitives/Icons/More.svelte +33 -33
  138. package/dist/primitives/Icons/MoreHori.spec.js +67 -67
  139. package/dist/primitives/Icons/MoreHori.svelte +34 -34
  140. package/dist/primitives/Icons/Notification.svelte +26 -26
  141. package/dist/primitives/Icons/Payment.svelte +26 -26
  142. package/dist/primitives/Icons/Profile.svelte +33 -33
  143. package/dist/primitives/Icons/Reload.svelte +41 -41
  144. package/dist/primitives/Icons/Shows.svelte +33 -33
  145. package/dist/primitives/Icons/Signout.svelte +33 -33
  146. package/dist/primitives/Icons/SunIcon.svelte +19 -19
  147. package/dist/primitives/Icons/TiktokIcon.svelte +13 -13
  148. package/dist/primitives/Icons/TrashBinOutline.svelte +19 -19
  149. package/dist/primitives/Icons/TwitterIcon.svelte +13 -13
  150. package/dist/primitives/Icons/WarningIcon.spec.js +30 -30
  151. package/dist/primitives/Icons/WarningIcon.svelte +24 -24
  152. package/dist/primitives/Input/Input.spec.js +573 -573
  153. package/dist/primitives/Input/Input.stories.svelte +139 -139
  154. package/dist/primitives/Input/Input.svelte +444 -444
  155. package/dist/primitives/Input/Select.spec.js +218 -218
  156. package/dist/primitives/Input/Select.stories.svelte +112 -112
  157. package/dist/primitives/Input/Select.svelte +232 -232
  158. package/dist/primitives/Input/Textarea.stories.svelte +137 -137
  159. package/dist/primitives/Input/Textarea.svelte +79 -79
  160. package/dist/primitives/Label/Label.svelte +37 -37
  161. package/dist/primitives/Modal/Modal.spec.js +95 -95
  162. package/dist/primitives/Modal/Modal.stories.svelte +86 -86
  163. package/dist/primitives/Modal/Modal.svelte +158 -158
  164. package/dist/primitives/Pagination/Pagination.stories.svelte +76 -76
  165. package/dist/primitives/Pagination/Pagination.svelte +261 -261
  166. package/dist/primitives/Radio/Radio.stories.svelte +80 -80
  167. package/dist/primitives/Radio/Radio.svelte +67 -67
  168. package/dist/primitives/Skeleton/CardPlaceholder.svelte +87 -87
  169. package/dist/primitives/Skeleton/ImagePlaceholder.svelte +59 -59
  170. package/dist/primitives/Skeleton/ListPlaceholder.svelte +76 -76
  171. package/dist/primitives/Skeleton/Skeleton.stories.svelte +151 -151
  172. package/dist/primitives/Skeleton/Skeleton.svelte +52 -52
  173. package/dist/primitives/Spinner/Spinner.spec.js +75 -75
  174. package/dist/primitives/Spinner/Spinner.stories.svelte +29 -29
  175. package/dist/primitives/Spinner/Spinner.svelte +57 -57
  176. package/dist/primitives/Tabs/TabItem.svelte +51 -51
  177. package/dist/primitives/Tabs/Tabs.stories.svelte +112 -112
  178. package/dist/primitives/Tabs/Tabs.svelte +128 -128
  179. package/dist/primitives/Toggle.spec.js +127 -127
  180. package/dist/primitives/Toggle.stories.svelte +92 -92
  181. package/dist/primitives/Toggle.svelte +71 -71
  182. package/dist/primitives/Typography/Typography.svelte +53 -53
  183. package/dist/primitives/ValidationError.spec.js +103 -103
  184. package/dist/primitives/ValidationError.stories.svelte +111 -111
  185. package/dist/primitives/ValidationError.svelte +29 -29
  186. package/dist/recipes/CropImage/CropImage.spec.js +216 -216
  187. package/dist/recipes/CropImage/CropImage.stories.svelte +104 -104
  188. package/dist/recipes/CropImage/CropImage.svelte +238 -238
  189. package/dist/recipes/ImageUploader/ImageUploader.stories.svelte +125 -125
  190. package/dist/recipes/ImageUploader/ImageUploader.svelte +980 -980
  191. package/dist/recipes/Toaster/Toaster.stories.svelte +62 -62
  192. package/dist/recipes/feedback/EmptyState/EmptyState.svelte +47 -47
  193. package/dist/recipes/feedback/ErrorDisplay.spec.js +69 -69
  194. package/dist/recipes/feedback/ErrorDisplay.stories.svelte +112 -112
  195. package/dist/recipes/feedback/ErrorDisplay.svelte +38 -38
  196. package/dist/recipes/feedback/StatusIndicator/StatusIndicator.spec.js +129 -129
  197. package/dist/recipes/feedback/StatusIndicator/StatusIndicator.svelte +167 -167
  198. package/dist/recipes/fields/CheckboxField.svelte +85 -85
  199. package/dist/recipes/fields/FormField.svelte +58 -58
  200. package/dist/recipes/fields/RadioGroup.svelte +95 -95
  201. package/dist/recipes/fields/SelectField.svelte +82 -82
  202. package/dist/recipes/fields/TextareaField.svelte +101 -101
  203. package/dist/recipes/fields/ToggleField.svelte +60 -60
  204. package/dist/recipes/fields/index.js +7 -7
  205. package/dist/recipes/inputs/MultiSelect.spec.js +257 -257
  206. package/dist/recipes/inputs/MultiSelect.stories.svelte +133 -133
  207. package/dist/recipes/inputs/MultiSelect.svelte +244 -244
  208. package/dist/recipes/inputs/OTPInput.spec.js +238 -238
  209. package/dist/recipes/inputs/OTPInput.stories.svelte +162 -162
  210. package/dist/recipes/inputs/OTPInput.svelte +102 -102
  211. package/dist/recipes/inputs/PasswordInput.svelte +100 -100
  212. package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.spec.js +173 -173
  213. package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.svelte +108 -108
  214. package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.spec.js +300 -300
  215. package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.stories.svelte +165 -165
  216. package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte +337 -337
  217. package/dist/recipes/inputs/Search.svelte +85 -85
  218. package/dist/recipes/inputs/SelectDropdown.svelte +161 -161
  219. package/dist/recipes/modals/AlertModal.svelte +130 -130
  220. package/dist/recipes/modals/ConfirmationModal.spec.js +191 -191
  221. package/dist/recipes/modals/ConfirmationModal.stories.svelte +119 -119
  222. package/dist/recipes/modals/ConfirmationModal.svelte +152 -152
  223. package/dist/recipes/modals/InputModal.svelte +182 -182
  224. package/dist/recipes/modals/ModalStateManager.spec.js +100 -100
  225. package/dist/recipes/modals/ModalStateManager.svelte +77 -77
  226. package/dist/recipes/modals/ModalTestWrapper.svelte +65 -65
  227. package/dist/recipes/modals/StatusModal.svelte +206 -206
  228. package/dist/services/EventService.js +75 -75
  229. package/dist/services/EventService.spec.js +217 -217
  230. package/dist/services/ShowService.spec.js +342 -342
  231. package/dist/stores/auth.js +93 -6
  232. package/dist/stores/auth.spec.js +310 -2
  233. package/dist/stores/toaster.js +13 -13
  234. package/dist/stories/ButtonAuditReview.stories.svelte +14 -14
  235. package/dist/stories/ButtonAuditReview.svelte +427 -427
  236. package/dist/stories/PatternsGallery.stories.svelte +19 -19
  237. package/dist/stories/PatternsGallery.svelte +388 -388
  238. package/dist/stories/PrimitivesGallery.stories.svelte +19 -19
  239. package/dist/stories/PrimitivesGallery.svelte +752 -752
  240. package/dist/stories/RecipesGallery.stories.svelte +19 -19
  241. package/dist/stories/RecipesGallery.svelte +441 -441
  242. package/dist/stories/button-audit-manifest.json +11186 -11186
  243. package/dist/tailwind/preset.cjs +82 -82
  244. package/dist/telemetry.js +357 -357
  245. package/dist/tokens/tokens.css +87 -87
  246. package/dist/utils/apiConfig.js +49 -49
  247. package/dist/utils/utils.js +9 -1
  248. package/package.json +233 -191
@@ -0,0 +1,112 @@
1
+ /**
2
+ * DateTime Constants
3
+ *
4
+ * Centralized constants for datetime operations.
5
+ * Use these instead of magic numbers throughout the codebase.
6
+ *
7
+ * @module datetime/constants
8
+ */
9
+ /**
10
+ * Duration constants in milliseconds.
11
+ */
12
+ export const DURATIONS = {
13
+ /** One second in milliseconds */
14
+ SECOND: 1000,
15
+ /** One minute in milliseconds */
16
+ MINUTE: 60 * 1000,
17
+ /** One hour in milliseconds */
18
+ HOUR: 60 * 60 * 1000,
19
+ /** One day in milliseconds */
20
+ DAY: 24 * 60 * 60 * 1000,
21
+ /** One week in milliseconds */
22
+ WEEK: 7 * 24 * 60 * 60 * 1000,
23
+ };
24
+ /**
25
+ * Duration constants in minutes.
26
+ */
27
+ export const DURATIONS_MINUTES = {
28
+ /** One hour in minutes */
29
+ HOUR: 60,
30
+ /** One day in minutes */
31
+ DAY: 24 * 60,
32
+ /** One week in minutes */
33
+ WEEK: 7 * 24 * 60,
34
+ };
35
+ /**
36
+ * Date format strings for use with date-fns.
37
+ */
38
+ export const DATE_FORMATS = {
39
+ /** API format: UTC ISO string */
40
+ API: "yyyy-MM-dd'T'HH:mm:ss'Z'",
41
+ /** Date for API without time */
42
+ API_DATE: 'yyyy-MM-dd',
43
+ /** Display date (e.g., "Dec 20, 2025") */
44
+ DISPLAY_DATE: 'MMM d, yyyy',
45
+ /** Display date without year (e.g., "Dec 20") */
46
+ DISPLAY_DATE_SHORT: 'MMM d',
47
+ /** Display time (e.g., "7:00 PM") */
48
+ DISPLAY_TIME: 'h:mm a',
49
+ /** Display time with seconds (e.g., "7:00:00 PM") */
50
+ DISPLAY_TIME_SECONDS: 'h:mm:ss a',
51
+ /** Display datetime (e.g., "Dec 20, 2025 at 7:00 PM") */
52
+ DISPLAY_DATETIME: "MMM d, yyyy 'at' h:mm a",
53
+ /** Display full datetime with day (e.g., "Mon, Dec 20, 2025 at 7:00 PM") */
54
+ DISPLAY_DATETIME_FULL: "EEE, MMM d, yyyy 'at' h:mm a",
55
+ /** Day of week short (e.g., "Mon") */
56
+ DAY_SHORT: 'EEE',
57
+ /** Day of week full (e.g., "Monday") */
58
+ DAY_FULL: 'EEEE',
59
+ /** Month short (e.g., "Dec") */
60
+ MONTH_SHORT: 'MMM',
61
+ /** Month full (e.g., "December") */
62
+ MONTH_FULL: 'MMMM',
63
+ /** Year only (e.g., "2025") */
64
+ YEAR: 'yyyy',
65
+ /** 24-hour time (e.g., "19:00") */
66
+ TIME_24H: 'HH:mm',
67
+ };
68
+ /**
69
+ * Commonly used US timezones for quick selection.
70
+ */
71
+ export const COMMON_US_TIMEZONES = [
72
+ { id: 'America/Los_Angeles', label: 'Pacific Time (PT)', abbr: 'PT' },
73
+ { id: 'America/Denver', label: 'Mountain Time (MT)', abbr: 'MT' },
74
+ { id: 'America/Chicago', label: 'Central Time (CT)', abbr: 'CT' },
75
+ { id: 'America/New_York', label: 'Eastern Time (ET)', abbr: 'ET' },
76
+ { id: 'America/Phoenix', label: 'Arizona (no DST)', abbr: 'AZ' },
77
+ { id: 'Pacific/Honolulu', label: 'Hawaii Time (HT)', abbr: 'HT' },
78
+ { id: 'America/Anchorage', label: 'Alaska Time (AKT)', abbr: 'AKT' },
79
+ ];
80
+ /**
81
+ * Default timezone when none is specified (should rarely be used).
82
+ * Prefer explicitly passing timezone in all operations.
83
+ */
84
+ export const DEFAULT_TIMEZONE = 'America/Los_Angeles';
85
+ /**
86
+ * Relative time thresholds for formatRelativeTime.
87
+ */
88
+ export const RELATIVE_TIME_THRESHOLDS = {
89
+ /** Under this many seconds, show "just now" */
90
+ JUST_NOW_SECONDS: 60,
91
+ /** Under this many minutes, show "X minutes ago/from now" */
92
+ MINUTES_THRESHOLD: 60,
93
+ /** Under this many hours, show "X hours ago/from now" */
94
+ HOURS_THRESHOLD: 24,
95
+ /** Under this many days, show "X days ago/from now" */
96
+ DAYS_THRESHOLD: 7,
97
+ /** Under this many weeks, show "X weeks ago/from now" */
98
+ WEEKS_THRESHOLD: 4,
99
+ };
100
+ /**
101
+ * MicDrop-specific event defaults.
102
+ */
103
+ export const EVENT_DEFAULTS = {
104
+ /** Default event duration in minutes */
105
+ DEFAULT_DURATION_MINUTES: 120,
106
+ /** Minimum event duration in minutes */
107
+ MIN_DURATION_MINUTES: 15,
108
+ /** Maximum event duration in minutes (24 hours) */
109
+ MAX_DURATION_MINUTES: 24 * 60,
110
+ /** Default doors open time before event start (minutes) */
111
+ DEFAULT_DOORS_BEFORE_MINUTES: 30,
112
+ };
@@ -0,0 +1,158 @@
1
+ /**
2
+ * DateTime Formatting Functions
3
+ *
4
+ * All formatting functions require an explicit timezone parameter.
5
+ * No defaults - timezone must always be provided.
6
+ *
7
+ * @module datetime/format
8
+ */
9
+ import type { DateParts, FormatOptions, ISODateString, TimezoneId } from './types';
10
+ /**
11
+ * Formats a UTC datetime as a time string in the specified timezone.
12
+ *
13
+ * @param utcIso - UTC ISO datetime string
14
+ * @param timezone - IANA timezone ID
15
+ * @param options - Optional formatting options
16
+ * @returns Formatted time (e.g., "7:00 PM")
17
+ * @throws {DateTimeError} If timezone or ISO string is invalid
18
+ *
19
+ * @example
20
+ * formatEventTime('2023-12-25T03:00:00Z', 'America/Los_Angeles')
21
+ * // "7:00 PM" (Dec 24 in LA)
22
+ */
23
+ export declare function formatEventTime(utcIso: ISODateString, timezone: TimezoneId, options?: FormatOptions): string;
24
+ /**
25
+ * Formats a UTC datetime as a date string in the specified timezone.
26
+ *
27
+ * @param utcIso - UTC ISO datetime string
28
+ * @param timezone - IANA timezone ID
29
+ * @param options - Optional formatting options
30
+ * @returns Formatted date (e.g., "Dec 20, 2025")
31
+ * @throws {DateTimeError} If timezone or ISO string is invalid
32
+ *
33
+ * @example
34
+ * formatEventDate('2023-12-25T03:00:00Z', 'America/Los_Angeles')
35
+ * // "Dec 24, 2023" (still Dec 24 in LA at 7 PM)
36
+ */
37
+ export declare function formatEventDate(utcIso: ISODateString, timezone: TimezoneId, options?: FormatOptions): string;
38
+ /**
39
+ * Formats a UTC datetime as a full datetime string in the specified timezone.
40
+ *
41
+ * @param utcIso - UTC ISO datetime string
42
+ * @param timezone - IANA timezone ID
43
+ * @param options - Optional formatting options
44
+ * @returns Formatted datetime (e.g., "Dec 20, 2025 at 7:00 PM")
45
+ * @throws {DateTimeError} If timezone or ISO string is invalid
46
+ *
47
+ * @example
48
+ * formatEventDateTime('2023-12-26T03:00:00Z', 'America/Los_Angeles')
49
+ * // "Dec 25, 2023 at 7:00 PM"
50
+ */
51
+ export declare function formatEventDateTime(utcIso: ISODateString, timezone: TimezoneId, options?: FormatOptions): string;
52
+ /**
53
+ * Formats a time range in the specified timezone.
54
+ *
55
+ * @param startUtc - Start time as UTC ISO string
56
+ * @param endUtc - End time as UTC ISO string
57
+ * @param timezone - IANA timezone ID
58
+ * @returns Formatted time range (e.g., "7:00 PM - 10:00 PM")
59
+ * @throws {DateTimeError} If timezone or ISO strings are invalid
60
+ *
61
+ * @example
62
+ * formatTimeRange(
63
+ * '2023-12-25T03:00:00Z',
64
+ * '2023-12-25T06:00:00Z',
65
+ * 'America/Los_Angeles'
66
+ * )
67
+ * // "7:00 PM - 10:00 PM"
68
+ */
69
+ export declare function formatTimeRange(startUtc: ISODateString, endUtc: ISODateString, timezone: TimezoneId): string;
70
+ /**
71
+ * Formats a date range in the specified timezone.
72
+ * Handles same-day, same-month, and cross-month/year ranges intelligently.
73
+ *
74
+ * @param startUtc - Start date as UTC ISO string
75
+ * @param endUtc - End date as UTC ISO string
76
+ * @param timezone - IANA timezone ID
77
+ * @returns Formatted date range (e.g., "Dec 20 - 22, 2025" or "Dec 20 - Jan 5, 2026")
78
+ * @throws {DateTimeError} If timezone or ISO strings are invalid
79
+ *
80
+ * @example
81
+ * formatDateRange(
82
+ * '2023-12-20T08:00:00Z',
83
+ * '2023-12-22T08:00:00Z',
84
+ * 'America/Los_Angeles'
85
+ * )
86
+ * // "Dec 20 - 22, 2023"
87
+ */
88
+ export declare function formatDateRange(startUtc: ISODateString, endUtc: ISODateString, timezone: TimezoneId): string;
89
+ /**
90
+ * Formats a datetime as a relative time string (e.g., "2 hours ago", "in 3 days").
91
+ *
92
+ * @param utcIso - UTC ISO datetime string
93
+ * @param timezone - IANA timezone ID (used for consistency, though relative time is timezone-agnostic)
94
+ * @returns Relative time string
95
+ * @throws {DateTimeError} If timezone or ISO string is invalid
96
+ *
97
+ * @example
98
+ * formatRelativeTime(new Date(Date.now() - 30 * 60 * 1000).toISOString(), 'America/Los_Angeles')
99
+ * // "30 minutes ago"
100
+ */
101
+ export declare function formatRelativeTime(utcIso: ISODateString, timezone: TimezoneId): string;
102
+ /**
103
+ * Extracts date parts from a UTC datetime in the specified timezone.
104
+ *
105
+ * @param utcIso - UTC ISO datetime string
106
+ * @param timezone - IANA timezone ID
107
+ * @returns Object with day, month, date, and year
108
+ * @throws {DateTimeError} If timezone or ISO string is invalid
109
+ *
110
+ * @example
111
+ * getDateParts('2023-12-25T20:00:00Z', 'America/Los_Angeles')
112
+ * // { day: 'Mon', month: 'Dec', date: 25, year: 2023 }
113
+ */
114
+ export declare function getDateParts(utcIso: ISODateString, timezone: TimezoneId): DateParts;
115
+ /**
116
+ * Formats a datetime for display in notifications.
117
+ * Shows relative time for recent events, date for older ones.
118
+ *
119
+ * @param utcIso - UTC ISO datetime string
120
+ * @param timezone - IANA timezone ID
121
+ * @returns Formatted string suitable for notifications
122
+ */
123
+ export declare function formatNotificationTime(utcIso: ISODateString, timezone: TimezoneId): string;
124
+ /**
125
+ * Formats the day of week from a UTC datetime.
126
+ *
127
+ * @param utcIso - UTC ISO datetime string
128
+ * @param timezone - IANA timezone ID
129
+ * @param short - If true, returns short form (e.g., "Mon"), otherwise full (e.g., "Monday")
130
+ * @returns Day of week string
131
+ */
132
+ export declare function formatDayOfWeek(utcIso: ISODateString, timezone: TimezoneId, short?: boolean): string;
133
+ /**
134
+ * Formats the month from a UTC datetime.
135
+ *
136
+ * @param utcIso - UTC ISO datetime string
137
+ * @param timezone - IANA timezone ID
138
+ * @param short - If true, returns short form (e.g., "Dec"), otherwise full (e.g., "December")
139
+ * @returns Month string
140
+ */
141
+ export declare function formatMonth(utcIso: ISODateString, timezone: TimezoneId, short?: boolean): string;
142
+ /**
143
+ * Gets the hour in the specified timezone (0-23).
144
+ *
145
+ * @param utcIso - UTC ISO datetime string
146
+ * @param timezone - IANA timezone ID
147
+ * @returns Hour (0-23)
148
+ */
149
+ export declare function getHourInTimezone(utcIso: ISODateString, timezone: TimezoneId): number;
150
+ /**
151
+ * Gets the date string (YYYY-MM-DD) in the specified timezone.
152
+ *
153
+ * @param utcIso - UTC ISO datetime string
154
+ * @param timezone - IANA timezone ID
155
+ * @returns Date string in YYYY-MM-DD format
156
+ */
157
+ export declare function getDateInTimezone(utcIso: ISODateString, timezone: TimezoneId): string;
158
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/lib/datetime/format.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,aAAa,EACb,UAAU,EACX,MAAM,SAAS,CAAC;AA4CjB;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,UAAU,EACpB,OAAO,CAAC,EAAE,aAAa,GACtB,MAAM,CAMR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,UAAU,EACpB,OAAO,CAAC,EAAE,aAAa,GACtB,MAAM,CAOR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,UAAU,EACpB,OAAO,CAAC,EAAE,aAAa,GACtB,MAAM,CAiBR;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,UAAU,GACnB,MAAM,CAIR;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,UAAU,GACnB,MAAM,CA4BR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,UAAU,GACnB,MAAM,CAoDR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,UAAU,GACnB,SAAS,CASX;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,UAAU,GACnB,MAAM,CAkBR;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,UAAU,EACpB,KAAK,GAAE,OAAc,GACpB,MAAM,CAMR;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,UAAU,EACpB,KAAK,GAAE,OAAc,GACpB,MAAM,CAMR;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,UAAU,GACnB,MAAM,CAGR;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,UAAU,GACnB,MAAM,CAGR"}
@@ -0,0 +1,315 @@
1
+ /**
2
+ * DateTime Formatting Functions
3
+ *
4
+ * All formatting functions require an explicit timezone parameter.
5
+ * No defaults - timezone must always be provided.
6
+ *
7
+ * @module datetime/format
8
+ */
9
+ import { format } from 'date-fns';
10
+ import { toZonedTime } from 'date-fns-tz';
11
+ import { DATE_FORMATS, DURATIONS, RELATIVE_TIME_THRESHOLDS } from './constants';
12
+ import { isValidTimezone } from './timezone';
13
+ import { DateTimeError, DateTimeErrorCode } from './types';
14
+ /**
15
+ * Validates an ISO date string and returns a Date object.
16
+ * @internal
17
+ */
18
+ function parseAndValidateISO(utcIso) {
19
+ if (!utcIso || typeof utcIso !== 'string') {
20
+ throw new DateTimeError('ISO date string is required', DateTimeErrorCode.INVALID_ISO_STRING, { value: utcIso });
21
+ }
22
+ const date = new Date(utcIso);
23
+ if (isNaN(date.getTime())) {
24
+ throw new DateTimeError(`Invalid ISO date string: ${utcIso}`, DateTimeErrorCode.INVALID_ISO_STRING, { value: utcIso });
25
+ }
26
+ return date;
27
+ }
28
+ /**
29
+ * Validates timezone and returns zoned date.
30
+ * @internal
31
+ */
32
+ function getZonedDate(utcIso, timezone) {
33
+ if (!isValidTimezone(timezone)) {
34
+ throw new DateTimeError(`Invalid timezone: ${timezone}`, DateTimeErrorCode.INVALID_TIMEZONE, { timezone });
35
+ }
36
+ const date = parseAndValidateISO(utcIso);
37
+ return toZonedTime(date, timezone);
38
+ }
39
+ /**
40
+ * Formats a UTC datetime as a time string in the specified timezone.
41
+ *
42
+ * @param utcIso - UTC ISO datetime string
43
+ * @param timezone - IANA timezone ID
44
+ * @param options - Optional formatting options
45
+ * @returns Formatted time (e.g., "7:00 PM")
46
+ * @throws {DateTimeError} If timezone or ISO string is invalid
47
+ *
48
+ * @example
49
+ * formatEventTime('2023-12-25T03:00:00Z', 'America/Los_Angeles')
50
+ * // "7:00 PM" (Dec 24 in LA)
51
+ */
52
+ export function formatEventTime(utcIso, timezone, options) {
53
+ const zonedDate = getZonedDate(utcIso, timezone);
54
+ const formatStr = options?.includeSeconds
55
+ ? DATE_FORMATS.DISPLAY_TIME_SECONDS
56
+ : DATE_FORMATS.DISPLAY_TIME;
57
+ return format(zonedDate, formatStr);
58
+ }
59
+ /**
60
+ * Formats a UTC datetime as a date string in the specified timezone.
61
+ *
62
+ * @param utcIso - UTC ISO datetime string
63
+ * @param timezone - IANA timezone ID
64
+ * @param options - Optional formatting options
65
+ * @returns Formatted date (e.g., "Dec 20, 2025")
66
+ * @throws {DateTimeError} If timezone or ISO string is invalid
67
+ *
68
+ * @example
69
+ * formatEventDate('2023-12-25T03:00:00Z', 'America/Los_Angeles')
70
+ * // "Dec 24, 2023" (still Dec 24 in LA at 7 PM)
71
+ */
72
+ export function formatEventDate(utcIso, timezone, options) {
73
+ const zonedDate = getZonedDate(utcIso, timezone);
74
+ const formatStr = options?.includeYear === false
75
+ ? DATE_FORMATS.DISPLAY_DATE_SHORT
76
+ : DATE_FORMATS.DISPLAY_DATE;
77
+ return format(zonedDate, formatStr);
78
+ }
79
+ /**
80
+ * Formats a UTC datetime as a full datetime string in the specified timezone.
81
+ *
82
+ * @param utcIso - UTC ISO datetime string
83
+ * @param timezone - IANA timezone ID
84
+ * @param options - Optional formatting options
85
+ * @returns Formatted datetime (e.g., "Dec 20, 2025 at 7:00 PM")
86
+ * @throws {DateTimeError} If timezone or ISO string is invalid
87
+ *
88
+ * @example
89
+ * formatEventDateTime('2023-12-26T03:00:00Z', 'America/Los_Angeles')
90
+ * // "Dec 25, 2023 at 7:00 PM"
91
+ */
92
+ export function formatEventDateTime(utcIso, timezone, options) {
93
+ const zonedDate = getZonedDate(utcIso, timezone);
94
+ // Respect includeDate/includeTime options
95
+ const includeDate = options?.includeDate !== false;
96
+ const includeTime = options?.includeTime !== false;
97
+ if (includeDate && includeTime) {
98
+ return format(zonedDate, DATE_FORMATS.DISPLAY_DATETIME);
99
+ }
100
+ else if (includeDate && !includeTime) {
101
+ return format(zonedDate, DATE_FORMATS.DISPLAY_DATE);
102
+ }
103
+ else if (!includeDate && includeTime) {
104
+ return format(zonedDate, DATE_FORMATS.DISPLAY_TIME);
105
+ }
106
+ // Fallback to full datetime
107
+ return format(zonedDate, DATE_FORMATS.DISPLAY_DATETIME);
108
+ }
109
+ /**
110
+ * Formats a time range in the specified timezone.
111
+ *
112
+ * @param startUtc - Start time as UTC ISO string
113
+ * @param endUtc - End time as UTC ISO string
114
+ * @param timezone - IANA timezone ID
115
+ * @returns Formatted time range (e.g., "7:00 PM - 10:00 PM")
116
+ * @throws {DateTimeError} If timezone or ISO strings are invalid
117
+ *
118
+ * @example
119
+ * formatTimeRange(
120
+ * '2023-12-25T03:00:00Z',
121
+ * '2023-12-25T06:00:00Z',
122
+ * 'America/Los_Angeles'
123
+ * )
124
+ * // "7:00 PM - 10:00 PM"
125
+ */
126
+ export function formatTimeRange(startUtc, endUtc, timezone) {
127
+ const startTime = formatEventTime(startUtc, timezone);
128
+ const endTime = formatEventTime(endUtc, timezone);
129
+ return `${startTime} - ${endTime}`;
130
+ }
131
+ /**
132
+ * Formats a date range in the specified timezone.
133
+ * Handles same-day, same-month, and cross-month/year ranges intelligently.
134
+ *
135
+ * @param startUtc - Start date as UTC ISO string
136
+ * @param endUtc - End date as UTC ISO string
137
+ * @param timezone - IANA timezone ID
138
+ * @returns Formatted date range (e.g., "Dec 20 - 22, 2025" or "Dec 20 - Jan 5, 2026")
139
+ * @throws {DateTimeError} If timezone or ISO strings are invalid
140
+ *
141
+ * @example
142
+ * formatDateRange(
143
+ * '2023-12-20T08:00:00Z',
144
+ * '2023-12-22T08:00:00Z',
145
+ * 'America/Los_Angeles'
146
+ * )
147
+ * // "Dec 20 - 22, 2023"
148
+ */
149
+ export function formatDateRange(startUtc, endUtc, timezone) {
150
+ const startZoned = getZonedDate(startUtc, timezone);
151
+ const endZoned = getZonedDate(endUtc, timezone);
152
+ const startYear = startZoned.getFullYear();
153
+ const endYear = endZoned.getFullYear();
154
+ const startMonth = startZoned.getMonth();
155
+ const endMonth = endZoned.getMonth();
156
+ const startDay = startZoned.getDate();
157
+ const endDay = endZoned.getDate();
158
+ // Same day
159
+ if (startYear === endYear && startMonth === endMonth && startDay === endDay) {
160
+ return format(startZoned, DATE_FORMATS.DISPLAY_DATE);
161
+ }
162
+ // Same month and year
163
+ if (startYear === endYear && startMonth === endMonth) {
164
+ return `${format(startZoned, 'MMM d')} - ${endDay}, ${startYear}`;
165
+ }
166
+ // Same year, different months
167
+ if (startYear === endYear) {
168
+ return `${format(startZoned, 'MMM d')} - ${format(endZoned, 'MMM d')}, ${startYear}`;
169
+ }
170
+ // Different years
171
+ return `${format(startZoned, DATE_FORMATS.DISPLAY_DATE)} - ${format(endZoned, DATE_FORMATS.DISPLAY_DATE)}`;
172
+ }
173
+ /**
174
+ * Formats a datetime as a relative time string (e.g., "2 hours ago", "in 3 days").
175
+ *
176
+ * @param utcIso - UTC ISO datetime string
177
+ * @param timezone - IANA timezone ID (used for consistency, though relative time is timezone-agnostic)
178
+ * @returns Relative time string
179
+ * @throws {DateTimeError} If timezone or ISO string is invalid
180
+ *
181
+ * @example
182
+ * formatRelativeTime(new Date(Date.now() - 30 * 60 * 1000).toISOString(), 'America/Los_Angeles')
183
+ * // "30 minutes ago"
184
+ */
185
+ export function formatRelativeTime(utcIso, timezone) {
186
+ // Validate inputs
187
+ if (!isValidTimezone(timezone)) {
188
+ throw new DateTimeError(`Invalid timezone: ${timezone}`, DateTimeErrorCode.INVALID_TIMEZONE, { timezone });
189
+ }
190
+ const date = parseAndValidateISO(utcIso);
191
+ const now = new Date();
192
+ const diffMs = date.getTime() - now.getTime();
193
+ const absDiffMs = Math.abs(diffMs);
194
+ const isPast = diffMs < 0;
195
+ const seconds = Math.floor(absDiffMs / DURATIONS.SECOND);
196
+ const minutes = Math.floor(absDiffMs / DURATIONS.MINUTE);
197
+ const hours = Math.floor(absDiffMs / DURATIONS.HOUR);
198
+ const days = Math.floor(absDiffMs / DURATIONS.DAY);
199
+ const weeks = Math.floor(absDiffMs / DURATIONS.WEEK);
200
+ const formatUnit = (value, unit) => {
201
+ const plural = value === 1 ? '' : 's';
202
+ if (isPast) {
203
+ return `${value} ${unit}${plural} ago`;
204
+ }
205
+ return `in ${value} ${unit}${plural}`;
206
+ };
207
+ if (seconds < RELATIVE_TIME_THRESHOLDS.JUST_NOW_SECONDS) {
208
+ return 'just now';
209
+ }
210
+ if (minutes < RELATIVE_TIME_THRESHOLDS.MINUTES_THRESHOLD) {
211
+ return formatUnit(minutes, 'minute');
212
+ }
213
+ if (hours < RELATIVE_TIME_THRESHOLDS.HOURS_THRESHOLD) {
214
+ return formatUnit(hours, 'hour');
215
+ }
216
+ if (days < RELATIVE_TIME_THRESHOLDS.DAYS_THRESHOLD) {
217
+ return formatUnit(days, 'day');
218
+ }
219
+ if (weeks < RELATIVE_TIME_THRESHOLDS.WEEKS_THRESHOLD) {
220
+ return formatUnit(weeks, 'week');
221
+ }
222
+ // For older dates, show the actual date
223
+ return formatEventDate(utcIso, timezone);
224
+ }
225
+ /**
226
+ * Extracts date parts from a UTC datetime in the specified timezone.
227
+ *
228
+ * @param utcIso - UTC ISO datetime string
229
+ * @param timezone - IANA timezone ID
230
+ * @returns Object with day, month, date, and year
231
+ * @throws {DateTimeError} If timezone or ISO string is invalid
232
+ *
233
+ * @example
234
+ * getDateParts('2023-12-25T20:00:00Z', 'America/Los_Angeles')
235
+ * // { day: 'Mon', month: 'Dec', date: 25, year: 2023 }
236
+ */
237
+ export function getDateParts(utcIso, timezone) {
238
+ const zonedDate = getZonedDate(utcIso, timezone);
239
+ return {
240
+ day: format(zonedDate, DATE_FORMATS.DAY_SHORT),
241
+ month: format(zonedDate, DATE_FORMATS.MONTH_SHORT),
242
+ date: zonedDate.getDate(),
243
+ year: zonedDate.getFullYear(),
244
+ };
245
+ }
246
+ /**
247
+ * Formats a datetime for display in notifications.
248
+ * Shows relative time for recent events, date for older ones.
249
+ *
250
+ * @param utcIso - UTC ISO datetime string
251
+ * @param timezone - IANA timezone ID
252
+ * @returns Formatted string suitable for notifications
253
+ */
254
+ export function formatNotificationTime(utcIso, timezone) {
255
+ const date = parseAndValidateISO(utcIso);
256
+ const now = new Date();
257
+ const diffMs = now.getTime() - date.getTime();
258
+ // Less than 24 hours ago
259
+ if (diffMs < DURATIONS.DAY) {
260
+ return formatRelativeTime(utcIso, timezone);
261
+ }
262
+ // Less than 7 days ago
263
+ if (diffMs < DURATIONS.WEEK) {
264
+ const zonedDate = getZonedDate(utcIso, timezone);
265
+ return format(zonedDate, "EEEE 'at' h:mm a");
266
+ }
267
+ // Older - show full date
268
+ return formatEventDateTime(utcIso, timezone);
269
+ }
270
+ /**
271
+ * Formats the day of week from a UTC datetime.
272
+ *
273
+ * @param utcIso - UTC ISO datetime string
274
+ * @param timezone - IANA timezone ID
275
+ * @param short - If true, returns short form (e.g., "Mon"), otherwise full (e.g., "Monday")
276
+ * @returns Day of week string
277
+ */
278
+ export function formatDayOfWeek(utcIso, timezone, short = true) {
279
+ const zonedDate = getZonedDate(utcIso, timezone);
280
+ return format(zonedDate, short ? DATE_FORMATS.DAY_SHORT : DATE_FORMATS.DAY_FULL);
281
+ }
282
+ /**
283
+ * Formats the month from a UTC datetime.
284
+ *
285
+ * @param utcIso - UTC ISO datetime string
286
+ * @param timezone - IANA timezone ID
287
+ * @param short - If true, returns short form (e.g., "Dec"), otherwise full (e.g., "December")
288
+ * @returns Month string
289
+ */
290
+ export function formatMonth(utcIso, timezone, short = true) {
291
+ const zonedDate = getZonedDate(utcIso, timezone);
292
+ return format(zonedDate, short ? DATE_FORMATS.MONTH_SHORT : DATE_FORMATS.MONTH_FULL);
293
+ }
294
+ /**
295
+ * Gets the hour in the specified timezone (0-23).
296
+ *
297
+ * @param utcIso - UTC ISO datetime string
298
+ * @param timezone - IANA timezone ID
299
+ * @returns Hour (0-23)
300
+ */
301
+ export function getHourInTimezone(utcIso, timezone) {
302
+ const zonedDate = getZonedDate(utcIso, timezone);
303
+ return zonedDate.getHours();
304
+ }
305
+ /**
306
+ * Gets the date string (YYYY-MM-DD) in the specified timezone.
307
+ *
308
+ * @param utcIso - UTC ISO datetime string
309
+ * @param timezone - IANA timezone ID
310
+ * @returns Date string in YYYY-MM-DD format
311
+ */
312
+ export function getDateInTimezone(utcIso, timezone) {
313
+ const zonedDate = getZonedDate(utcIso, timezone);
314
+ return format(zonedDate, DATE_FORMATS.API_DATE);
315
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * DateTime Module
3
+ *
4
+ * Centralized date/time handling for the MicDrop platform.
5
+ * All datetime operations should use this module to ensure consistent
6
+ * timezone handling across the application.
7
+ *
8
+ * ## Golden Rules
9
+ *
10
+ * 1. **Backend is King** - All API requests send/receive UTC ISO strings
11
+ * 2. **Display is Local** - All UI components receive UTC + Timezone ID
12
+ * 3. **No `new Date()` in components** - Use these helpers instead
13
+ * 4. **Timezone is always required** - Every function requires explicit timezone
14
+ *
15
+ * ## Usage Examples
16
+ *
17
+ * ```typescript
18
+ * import * as datetime from './';
19
+ *
20
+ * // Get venue timezone
21
+ * const tz = datetime.getVenueTimezone(venue);
22
+ *
23
+ * // Format for display
24
+ * const time = datetime.formatEventTime(event.startTime, tz);
25
+ * const date = datetime.formatEventDate(event.startTime, tz);
26
+ *
27
+ * // Parse form input to UTC for API
28
+ * const utc = datetime.combineDateAndTime('2023-12-25', '19:00', tz);
29
+ *
30
+ * // Parse API response for form
31
+ * const { date, time } = datetime.parseDateTimeFromAPI(event.startTime, tz);
32
+ * ```
33
+ *
34
+ * @module datetime
35
+ */
36
+ export type { DateParts, FormatOptions, FormattedTimeRange, ISODateString, LocalDateString, LocalDateTimeString, LocalTimeString, TimeRange, TimezoneId, VenueWithTimezone, } from './types';
37
+ export { DateTimeError, DateTimeErrorCode } from './types';
38
+ export { COMMON_US_TIMEZONES, DATE_FORMATS, DEFAULT_TIMEZONE, DURATIONS, DURATIONS_MINUTES, EVENT_DEFAULTS, RELATIVE_TIME_THRESHOLDS, } from './constants';
39
+ export { getTimezoneDisplayName, getTimezoneOffset, getUserTimezone, getVenueTimezone, isDST, isValidTimezone, normalizeTimezone, } from './timezone';
40
+ export { formatDateRange, formatDayOfWeek, formatEventDate, formatEventDateTime, formatEventTime, formatMonth, formatNotificationTime, formatRelativeTime, formatTimeRange, getDateInTimezone, getDateParts, getHourInTimezone, } from './format';
41
+ export { combineDateAndTime, formatDateTimeForAPI, isNextDayTime, minutesToTimeString, parseDateTimeFromAPI, parseEndOfDay, parseLocalToUTC, parseStartOfDay, parseTimeToMinutes, parseUTCToLocal, stripNextDayPrefix, } from './parse';
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/datetime/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAGH,YAAY,EACV,SAAS,EACT,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,SAAS,EACT,UAAU,EACV,iBAAiB,GAClB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAG3D,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,SAAS,EACT,iBAAiB,EACjB,cAAc,EACd,wBAAwB,GACzB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,KAAK,EACL,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,eAAe,EACf,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,kBAAkB,GACnB,MAAM,SAAS,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * DateTime Module
3
+ *
4
+ * Centralized date/time handling for the MicDrop platform.
5
+ * All datetime operations should use this module to ensure consistent
6
+ * timezone handling across the application.
7
+ *
8
+ * ## Golden Rules
9
+ *
10
+ * 1. **Backend is King** - All API requests send/receive UTC ISO strings
11
+ * 2. **Display is Local** - All UI components receive UTC + Timezone ID
12
+ * 3. **No `new Date()` in components** - Use these helpers instead
13
+ * 4. **Timezone is always required** - Every function requires explicit timezone
14
+ *
15
+ * ## Usage Examples
16
+ *
17
+ * ```typescript
18
+ * import * as datetime from './';
19
+ *
20
+ * // Get venue timezone
21
+ * const tz = datetime.getVenueTimezone(venue);
22
+ *
23
+ * // Format for display
24
+ * const time = datetime.formatEventTime(event.startTime, tz);
25
+ * const date = datetime.formatEventDate(event.startTime, tz);
26
+ *
27
+ * // Parse form input to UTC for API
28
+ * const utc = datetime.combineDateAndTime('2023-12-25', '19:00', tz);
29
+ *
30
+ * // Parse API response for form
31
+ * const { date, time } = datetime.parseDateTimeFromAPI(event.startTime, tz);
32
+ * ```
33
+ *
34
+ * @module datetime
35
+ */
36
+ export { DateTimeError, DateTimeErrorCode } from './types';
37
+ // Constants
38
+ export { COMMON_US_TIMEZONES, DATE_FORMATS, DEFAULT_TIMEZONE, DURATIONS, DURATIONS_MINUTES, EVENT_DEFAULTS, RELATIVE_TIME_THRESHOLDS, } from './constants';
39
+ // Timezone utilities
40
+ export { getTimezoneDisplayName, getTimezoneOffset, getUserTimezone, getVenueTimezone, isDST, isValidTimezone, normalizeTimezone, } from './timezone';
41
+ // Format functions
42
+ export { formatDateRange, formatDayOfWeek, formatEventDate, formatEventDateTime, formatEventTime, formatMonth, formatNotificationTime, formatRelativeTime, formatTimeRange, getDateInTimezone, getDateParts, getHourInTimezone, } from './format';
43
+ // Parse functions
44
+ export { combineDateAndTime, formatDateTimeForAPI, isNextDayTime, minutesToTimeString, parseDateTimeFromAPI, parseEndOfDay, parseLocalToUTC, parseStartOfDay, parseTimeToMinutes, parseUTCToLocal, stripNextDayPrefix, } from './parse';