@cdx-ui/formatters 0.0.1-beta.132

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 (464) hide show
  1. package/README.md +108 -0
  2. package/lib/commonjs/dates/calendar/formatCalendarMonthYear.js +28 -0
  3. package/lib/commonjs/dates/calendar/formatCalendarMonthYear.js.map +1 -0
  4. package/lib/commonjs/dates/calendar/formatDateTimeListDateRow.js +40 -0
  5. package/lib/commonjs/dates/calendar/formatDateTimeListDateRow.js.map +1 -0
  6. package/lib/commonjs/dates/calendar/formatMonthCalendarMonth.js +28 -0
  7. package/lib/commonjs/dates/calendar/formatMonthCalendarMonth.js.map +1 -0
  8. package/lib/commonjs/dates/calendar/formatMonthCalendarYear.js +16 -0
  9. package/lib/commonjs/dates/calendar/formatMonthCalendarYear.js.map +1 -0
  10. package/lib/commonjs/dates/calendar/getCalendarWeekdayLabels.js +23 -0
  11. package/lib/commonjs/dates/calendar/getCalendarWeekdayLabels.js.map +1 -0
  12. package/lib/commonjs/dates/datetime/clampDateTimeId.js +27 -0
  13. package/lib/commonjs/dates/datetime/clampDateTimeId.js.map +1 -0
  14. package/lib/commonjs/dates/datetime/compareDateTimeIds.js +28 -0
  15. package/lib/commonjs/dates/datetime/compareDateTimeIds.js.map +1 -0
  16. package/lib/commonjs/dates/datetime/dateTimeId.js +38 -0
  17. package/lib/commonjs/dates/datetime/dateTimeId.js.map +1 -0
  18. package/lib/commonjs/dates/datetime/formatDateTimeId.js +27 -0
  19. package/lib/commonjs/dates/datetime/formatDateTimeId.js.map +1 -0
  20. package/lib/commonjs/dates/datetime/formatDateTimeListHour.js +21 -0
  21. package/lib/commonjs/dates/datetime/formatDateTimeListHour.js.map +1 -0
  22. package/lib/commonjs/dates/datetime/formatDateTimeListMinute.js +16 -0
  23. package/lib/commonjs/dates/datetime/formatDateTimeListMinute.js.map +1 -0
  24. package/lib/commonjs/dates/datetime/formatDateTimeListPeriod.js +17 -0
  25. package/lib/commonjs/dates/datetime/formatDateTimeListPeriod.js.map +1 -0
  26. package/lib/commonjs/dates/datetime/isLocaleHour12.js +30 -0
  27. package/lib/commonjs/dates/datetime/isLocaleHour12.js.map +1 -0
  28. package/lib/commonjs/dates/datetime/isValidDateTimeId.js +23 -0
  29. package/lib/commonjs/dates/datetime/isValidDateTimeId.js.map +1 -0
  30. package/lib/commonjs/dates/datetime/nowDateTimeId.js +57 -0
  31. package/lib/commonjs/dates/datetime/nowDateTimeId.js.map +1 -0
  32. package/lib/commonjs/dates/datetime/parseDateTimeId.js +29 -0
  33. package/lib/commonjs/dates/datetime/parseDateTimeId.js.map +1 -0
  34. package/lib/commonjs/dates/display/formatDateForDisplay.js +28 -0
  35. package/lib/commonjs/dates/display/formatDateForDisplay.js.map +1 -0
  36. package/lib/commonjs/dates/display/formatDateRangeForDisplay.js +25 -0
  37. package/lib/commonjs/dates/display/formatDateRangeForDisplay.js.map +1 -0
  38. package/lib/commonjs/dates/display/formatDateTimeForDisplay.js +34 -0
  39. package/lib/commonjs/dates/display/formatDateTimeForDisplay.js.map +1 -0
  40. package/lib/commonjs/dates/display/formatMonthForDisplay.js +33 -0
  41. package/lib/commonjs/dates/display/formatMonthForDisplay.js.map +1 -0
  42. package/lib/commonjs/dates/index.js +367 -0
  43. package/lib/commonjs/dates/index.js.map +1 -0
  44. package/lib/commonjs/dates/internal/brand.js +19 -0
  45. package/lib/commonjs/dates/internal/brand.js.map +1 -0
  46. package/lib/commonjs/dates/internal/calendarHelpers.js +22 -0
  47. package/lib/commonjs/dates/internal/calendarHelpers.js.map +1 -0
  48. package/lib/commonjs/dates/internal/clampHelpers.js +20 -0
  49. package/lib/commonjs/dates/internal/clampHelpers.js.map +1 -0
  50. package/lib/commonjs/dates/internal/dateIdToNativeDate.js +20 -0
  51. package/lib/commonjs/dates/internal/dateIdToNativeDate.js.map +1 -0
  52. package/lib/commonjs/dates/internal/intlCache.js +52 -0
  53. package/lib/commonjs/dates/internal/intlCache.js.map +1 -0
  54. package/lib/commonjs/dates/internal/intlCopy.js +72 -0
  55. package/lib/commonjs/dates/internal/intlCopy.js.map +1 -0
  56. package/lib/commonjs/dates/internal/segmentBuilders.js +98 -0
  57. package/lib/commonjs/dates/internal/segmentBuilders.js.map +1 -0
  58. package/lib/commonjs/dates/labels/dateComponentLabels.js +57 -0
  59. package/lib/commonjs/dates/labels/dateComponentLabels.js.map +1 -0
  60. package/lib/commonjs/dates/ranges/compareDateIds.js +26 -0
  61. package/lib/commonjs/dates/ranges/compareDateIds.js.map +1 -0
  62. package/lib/commonjs/dates/ranges/compareMonthIds.js +31 -0
  63. package/lib/commonjs/dates/ranges/compareMonthIds.js.map +1 -0
  64. package/lib/commonjs/dates/ranges/dateRangeAroundDay.js +25 -0
  65. package/lib/commonjs/dates/ranges/dateRangeAroundDay.js.map +1 -0
  66. package/lib/commonjs/dates/ranges/dateRangeFromLastNDays.js +28 -0
  67. package/lib/commonjs/dates/ranges/dateRangeFromLastNDays.js.map +1 -0
  68. package/lib/commonjs/dates/ranges/eachDateIdInRange.js +29 -0
  69. package/lib/commonjs/dates/ranges/eachDateIdInRange.js.map +1 -0
  70. package/lib/commonjs/dates/ranges/normalizeDateRange.js +23 -0
  71. package/lib/commonjs/dates/ranges/normalizeDateRange.js.map +1 -0
  72. package/lib/commonjs/dates/segments/applyDateSegmentChange.js +77 -0
  73. package/lib/commonjs/dates/segments/applyDateSegmentChange.js.map +1 -0
  74. package/lib/commonjs/dates/segments/formatDateSegment.js +19 -0
  75. package/lib/commonjs/dates/segments/formatDateSegment.js.map +1 -0
  76. package/lib/commonjs/dates/segments/getDateFieldSegments.js +44 -0
  77. package/lib/commonjs/dates/segments/getDateFieldSegments.js.map +1 -0
  78. package/lib/commonjs/dates/segments/getDateTimeFieldSegments.js +150 -0
  79. package/lib/commonjs/dates/segments/getDateTimeFieldSegments.js.map +1 -0
  80. package/lib/commonjs/dates/segments/getDateTimeSegmentVisibility.js +15 -0
  81. package/lib/commonjs/dates/segments/getDateTimeSegmentVisibility.js.map +1 -0
  82. package/lib/commonjs/dates/segments/getEmptyDateSegmentText.js +17 -0
  83. package/lib/commonjs/dates/segments/getEmptyDateSegmentText.js.map +1 -0
  84. package/lib/commonjs/dates/segments/parseDateSegment.js +26 -0
  85. package/lib/commonjs/dates/segments/parseDateSegment.js.map +1 -0
  86. package/lib/commonjs/dates/types.js +2 -0
  87. package/lib/commonjs/dates/types.js.map +1 -0
  88. package/lib/commonjs/dates/wire/clampDateParts.js +26 -0
  89. package/lib/commonjs/dates/wire/clampDateParts.js.map +1 -0
  90. package/lib/commonjs/dates/wire/clampMonthParts.js +23 -0
  91. package/lib/commonjs/dates/wire/clampMonthParts.js.map +1 -0
  92. package/lib/commonjs/dates/wire/dateId.js +50 -0
  93. package/lib/commonjs/dates/wire/dateId.js.map +1 -0
  94. package/lib/commonjs/dates/wire/formatDateId.js +25 -0
  95. package/lib/commonjs/dates/wire/formatDateId.js.map +1 -0
  96. package/lib/commonjs/dates/wire/formatMonthId.js +21 -0
  97. package/lib/commonjs/dates/wire/formatMonthId.js.map +1 -0
  98. package/lib/commonjs/dates/wire/isValidDateId.js +27 -0
  99. package/lib/commonjs/dates/wire/isValidDateId.js.map +1 -0
  100. package/lib/commonjs/dates/wire/isValidDateParts.js +18 -0
  101. package/lib/commonjs/dates/wire/isValidDateParts.js.map +1 -0
  102. package/lib/commonjs/dates/wire/isValidMonthId.js +27 -0
  103. package/lib/commonjs/dates/wire/isValidMonthId.js.map +1 -0
  104. package/lib/commonjs/dates/wire/isValidMonthParts.js +16 -0
  105. package/lib/commonjs/dates/wire/isValidMonthParts.js.map +1 -0
  106. package/lib/commonjs/dates/wire/monthId.js +47 -0
  107. package/lib/commonjs/dates/wire/monthId.js.map +1 -0
  108. package/lib/commonjs/dates/wire/parseDateId.js +29 -0
  109. package/lib/commonjs/dates/wire/parseDateId.js.map +1 -0
  110. package/lib/commonjs/dates/wire/parseMonthId.js +28 -0
  111. package/lib/commonjs/dates/wire/parseMonthId.js.map +1 -0
  112. package/lib/commonjs/dates/wire/toMonthId.js +22 -0
  113. package/lib/commonjs/dates/wire/toMonthId.js.map +1 -0
  114. package/lib/commonjs/dates/wire/todayDateId.js +17 -0
  115. package/lib/commonjs/dates/wire/todayDateId.js.map +1 -0
  116. package/lib/commonjs/dates/wire/todayMonthId.js +17 -0
  117. package/lib/commonjs/dates/wire/todayMonthId.js.map +1 -0
  118. package/lib/commonjs/formatNumber.js +50 -0
  119. package/lib/commonjs/formatNumber.js.map +1 -0
  120. package/lib/commonjs/index.js +326 -0
  121. package/lib/commonjs/index.js.map +1 -0
  122. package/lib/commonjs/package.json +1 -0
  123. package/lib/commonjs/types.js +2 -0
  124. package/lib/commonjs/types.js.map +1 -0
  125. package/lib/commonjs/utils.js +33 -0
  126. package/lib/commonjs/utils.js.map +1 -0
  127. package/lib/module/dates/calendar/formatCalendarMonthYear.js +24 -0
  128. package/lib/module/dates/calendar/formatCalendarMonthYear.js.map +1 -0
  129. package/lib/module/dates/calendar/formatDateTimeListDateRow.js +36 -0
  130. package/lib/module/dates/calendar/formatDateTimeListDateRow.js.map +1 -0
  131. package/lib/module/dates/calendar/formatMonthCalendarMonth.js +24 -0
  132. package/lib/module/dates/calendar/formatMonthCalendarMonth.js.map +1 -0
  133. package/lib/module/dates/calendar/formatMonthCalendarYear.js +12 -0
  134. package/lib/module/dates/calendar/formatMonthCalendarYear.js.map +1 -0
  135. package/lib/module/dates/calendar/getCalendarWeekdayLabels.js +19 -0
  136. package/lib/module/dates/calendar/getCalendarWeekdayLabels.js.map +1 -0
  137. package/lib/module/dates/datetime/clampDateTimeId.js +24 -0
  138. package/lib/module/dates/datetime/clampDateTimeId.js.map +1 -0
  139. package/lib/module/dates/datetime/compareDateTimeIds.js +24 -0
  140. package/lib/module/dates/datetime/compareDateTimeIds.js.map +1 -0
  141. package/lib/module/dates/datetime/dateTimeId.js +35 -0
  142. package/lib/module/dates/datetime/dateTimeId.js.map +1 -0
  143. package/lib/module/dates/datetime/formatDateTimeId.js +23 -0
  144. package/lib/module/dates/datetime/formatDateTimeId.js.map +1 -0
  145. package/lib/module/dates/datetime/formatDateTimeListHour.js +17 -0
  146. package/lib/module/dates/datetime/formatDateTimeListHour.js.map +1 -0
  147. package/lib/module/dates/datetime/formatDateTimeListMinute.js +12 -0
  148. package/lib/module/dates/datetime/formatDateTimeListMinute.js.map +1 -0
  149. package/lib/module/dates/datetime/formatDateTimeListPeriod.js +13 -0
  150. package/lib/module/dates/datetime/formatDateTimeListPeriod.js.map +1 -0
  151. package/lib/module/dates/datetime/isLocaleHour12.js +26 -0
  152. package/lib/module/dates/datetime/isLocaleHour12.js.map +1 -0
  153. package/lib/module/dates/datetime/isValidDateTimeId.js +19 -0
  154. package/lib/module/dates/datetime/isValidDateTimeId.js.map +1 -0
  155. package/lib/module/dates/datetime/nowDateTimeId.js +54 -0
  156. package/lib/module/dates/datetime/nowDateTimeId.js.map +1 -0
  157. package/lib/module/dates/datetime/parseDateTimeId.js +26 -0
  158. package/lib/module/dates/datetime/parseDateTimeId.js.map +1 -0
  159. package/lib/module/dates/display/formatDateForDisplay.js +24 -0
  160. package/lib/module/dates/display/formatDateForDisplay.js.map +1 -0
  161. package/lib/module/dates/display/formatDateRangeForDisplay.js +22 -0
  162. package/lib/module/dates/display/formatDateRangeForDisplay.js.map +1 -0
  163. package/lib/module/dates/display/formatDateTimeForDisplay.js +30 -0
  164. package/lib/module/dates/display/formatDateTimeForDisplay.js.map +1 -0
  165. package/lib/module/dates/display/formatMonthForDisplay.js +29 -0
  166. package/lib/module/dates/display/formatMonthForDisplay.js.map +1 -0
  167. package/lib/module/dates/index.js +59 -0
  168. package/lib/module/dates/index.js.map +1 -0
  169. package/lib/module/dates/internal/brand.js +12 -0
  170. package/lib/module/dates/internal/brand.js.map +1 -0
  171. package/lib/module/dates/internal/calendarHelpers.js +19 -0
  172. package/lib/module/dates/internal/calendarHelpers.js.map +1 -0
  173. package/lib/module/dates/internal/clampHelpers.js +14 -0
  174. package/lib/module/dates/internal/clampHelpers.js.map +1 -0
  175. package/lib/module/dates/internal/dateIdToNativeDate.js +16 -0
  176. package/lib/module/dates/internal/dateIdToNativeDate.js.map +1 -0
  177. package/lib/module/dates/internal/intlCache.js +47 -0
  178. package/lib/module/dates/internal/intlCache.js.map +1 -0
  179. package/lib/module/dates/internal/intlCopy.js +66 -0
  180. package/lib/module/dates/internal/intlCopy.js.map +1 -0
  181. package/lib/module/dates/internal/segmentBuilders.js +91 -0
  182. package/lib/module/dates/internal/segmentBuilders.js.map +1 -0
  183. package/lib/module/dates/labels/dateComponentLabels.js +50 -0
  184. package/lib/module/dates/labels/dateComponentLabels.js.map +1 -0
  185. package/lib/module/dates/ranges/compareDateIds.js +22 -0
  186. package/lib/module/dates/ranges/compareDateIds.js.map +1 -0
  187. package/lib/module/dates/ranges/compareMonthIds.js +27 -0
  188. package/lib/module/dates/ranges/compareMonthIds.js.map +1 -0
  189. package/lib/module/dates/ranges/dateRangeAroundDay.js +21 -0
  190. package/lib/module/dates/ranges/dateRangeAroundDay.js.map +1 -0
  191. package/lib/module/dates/ranges/dateRangeFromLastNDays.js +24 -0
  192. package/lib/module/dates/ranges/dateRangeFromLastNDays.js.map +1 -0
  193. package/lib/module/dates/ranges/eachDateIdInRange.js +26 -0
  194. package/lib/module/dates/ranges/eachDateIdInRange.js.map +1 -0
  195. package/lib/module/dates/ranges/normalizeDateRange.js +20 -0
  196. package/lib/module/dates/ranges/normalizeDateRange.js.map +1 -0
  197. package/lib/module/dates/segments/applyDateSegmentChange.js +73 -0
  198. package/lib/module/dates/segments/applyDateSegmentChange.js.map +1 -0
  199. package/lib/module/dates/segments/formatDateSegment.js +15 -0
  200. package/lib/module/dates/segments/formatDateSegment.js.map +1 -0
  201. package/lib/module/dates/segments/getDateFieldSegments.js +40 -0
  202. package/lib/module/dates/segments/getDateFieldSegments.js.map +1 -0
  203. package/lib/module/dates/segments/getDateTimeFieldSegments.js +147 -0
  204. package/lib/module/dates/segments/getDateTimeFieldSegments.js.map +1 -0
  205. package/lib/module/dates/segments/getDateTimeSegmentVisibility.js +11 -0
  206. package/lib/module/dates/segments/getDateTimeSegmentVisibility.js.map +1 -0
  207. package/lib/module/dates/segments/getEmptyDateSegmentText.js +13 -0
  208. package/lib/module/dates/segments/getEmptyDateSegmentText.js.map +1 -0
  209. package/lib/module/dates/segments/parseDateSegment.js +22 -0
  210. package/lib/module/dates/segments/parseDateSegment.js.map +1 -0
  211. package/lib/module/dates/types.js +2 -0
  212. package/lib/module/dates/types.js.map +1 -0
  213. package/lib/module/dates/wire/clampDateParts.js +22 -0
  214. package/lib/module/dates/wire/clampDateParts.js.map +1 -0
  215. package/lib/module/dates/wire/clampMonthParts.js +19 -0
  216. package/lib/module/dates/wire/clampMonthParts.js.map +1 -0
  217. package/lib/module/dates/wire/dateId.js +47 -0
  218. package/lib/module/dates/wire/dateId.js.map +1 -0
  219. package/lib/module/dates/wire/formatDateId.js +22 -0
  220. package/lib/module/dates/wire/formatDateId.js.map +1 -0
  221. package/lib/module/dates/wire/formatMonthId.js +17 -0
  222. package/lib/module/dates/wire/formatMonthId.js.map +1 -0
  223. package/lib/module/dates/wire/isValidDateId.js +23 -0
  224. package/lib/module/dates/wire/isValidDateId.js.map +1 -0
  225. package/lib/module/dates/wire/isValidDateParts.js +14 -0
  226. package/lib/module/dates/wire/isValidDateParts.js.map +1 -0
  227. package/lib/module/dates/wire/isValidMonthId.js +23 -0
  228. package/lib/module/dates/wire/isValidMonthId.js.map +1 -0
  229. package/lib/module/dates/wire/isValidMonthParts.js +12 -0
  230. package/lib/module/dates/wire/isValidMonthParts.js.map +1 -0
  231. package/lib/module/dates/wire/monthId.js +44 -0
  232. package/lib/module/dates/wire/monthId.js.map +1 -0
  233. package/lib/module/dates/wire/parseDateId.js +26 -0
  234. package/lib/module/dates/wire/parseDateId.js.map +1 -0
  235. package/lib/module/dates/wire/parseMonthId.js +25 -0
  236. package/lib/module/dates/wire/parseMonthId.js.map +1 -0
  237. package/lib/module/dates/wire/toMonthId.js +18 -0
  238. package/lib/module/dates/wire/toMonthId.js.map +1 -0
  239. package/lib/module/dates/wire/todayDateId.js +13 -0
  240. package/lib/module/dates/wire/todayDateId.js.map +1 -0
  241. package/lib/module/dates/wire/todayMonthId.js +13 -0
  242. package/lib/module/dates/wire/todayMonthId.js.map +1 -0
  243. package/lib/module/formatNumber.js +46 -0
  244. package/lib/module/formatNumber.js.map +1 -0
  245. package/lib/module/index.js +17 -0
  246. package/lib/module/index.js.map +1 -0
  247. package/lib/module/types.js +2 -0
  248. package/lib/module/types.js.map +1 -0
  249. package/lib/module/utils.js +29 -0
  250. package/lib/module/utils.js.map +1 -0
  251. package/lib/typescript/dates/calendar/formatCalendarMonthYear.d.ts +12 -0
  252. package/lib/typescript/dates/calendar/formatCalendarMonthYear.d.ts.map +1 -0
  253. package/lib/typescript/dates/calendar/formatDateTimeListDateRow.d.ts +13 -0
  254. package/lib/typescript/dates/calendar/formatDateTimeListDateRow.d.ts.map +1 -0
  255. package/lib/typescript/dates/calendar/formatMonthCalendarMonth.d.ts +13 -0
  256. package/lib/typescript/dates/calendar/formatMonthCalendarMonth.d.ts.map +1 -0
  257. package/lib/typescript/dates/calendar/formatMonthCalendarYear.d.ts +8 -0
  258. package/lib/typescript/dates/calendar/formatMonthCalendarYear.d.ts.map +1 -0
  259. package/lib/typescript/dates/calendar/getCalendarWeekdayLabels.d.ts +12 -0
  260. package/lib/typescript/dates/calendar/getCalendarWeekdayLabels.d.ts.map +1 -0
  261. package/lib/typescript/dates/datetime/clampDateTimeId.d.ts +16 -0
  262. package/lib/typescript/dates/datetime/clampDateTimeId.d.ts.map +1 -0
  263. package/lib/typescript/dates/datetime/compareDateTimeIds.d.ts +13 -0
  264. package/lib/typescript/dates/datetime/compareDateTimeIds.d.ts.map +1 -0
  265. package/lib/typescript/dates/datetime/dateTimeId.d.ts +18 -0
  266. package/lib/typescript/dates/datetime/dateTimeId.d.ts.map +1 -0
  267. package/lib/typescript/dates/datetime/formatDateTimeId.d.ts +12 -0
  268. package/lib/typescript/dates/datetime/formatDateTimeId.d.ts.map +1 -0
  269. package/lib/typescript/dates/datetime/formatDateTimeListHour.d.ts +11 -0
  270. package/lib/typescript/dates/datetime/formatDateTimeListHour.d.ts.map +1 -0
  271. package/lib/typescript/dates/datetime/formatDateTimeListMinute.d.ts +8 -0
  272. package/lib/typescript/dates/datetime/formatDateTimeListMinute.d.ts.map +1 -0
  273. package/lib/typescript/dates/datetime/formatDateTimeListPeriod.d.ts +9 -0
  274. package/lib/typescript/dates/datetime/formatDateTimeListPeriod.d.ts.map +1 -0
  275. package/lib/typescript/dates/datetime/isLocaleHour12.d.ts +12 -0
  276. package/lib/typescript/dates/datetime/isLocaleHour12.d.ts.map +1 -0
  277. package/lib/typescript/dates/datetime/isValidDateTimeId.d.ts +9 -0
  278. package/lib/typescript/dates/datetime/isValidDateTimeId.d.ts.map +1 -0
  279. package/lib/typescript/dates/datetime/nowDateTimeId.d.ts +14 -0
  280. package/lib/typescript/dates/datetime/nowDateTimeId.d.ts.map +1 -0
  281. package/lib/typescript/dates/datetime/parseDateTimeId.d.ts +9 -0
  282. package/lib/typescript/dates/datetime/parseDateTimeId.d.ts.map +1 -0
  283. package/lib/typescript/dates/display/formatDateForDisplay.d.ts +13 -0
  284. package/lib/typescript/dates/display/formatDateForDisplay.d.ts.map +1 -0
  285. package/lib/typescript/dates/display/formatDateRangeForDisplay.d.ts +16 -0
  286. package/lib/typescript/dates/display/formatDateRangeForDisplay.d.ts.map +1 -0
  287. package/lib/typescript/dates/display/formatDateTimeForDisplay.d.ts +13 -0
  288. package/lib/typescript/dates/display/formatDateTimeForDisplay.d.ts.map +1 -0
  289. package/lib/typescript/dates/display/formatMonthForDisplay.d.ts +13 -0
  290. package/lib/typescript/dates/display/formatMonthForDisplay.d.ts.map +1 -0
  291. package/lib/typescript/dates/index.d.ts +58 -0
  292. package/lib/typescript/dates/index.d.ts.map +1 -0
  293. package/lib/typescript/dates/internal/brand.d.ts +11 -0
  294. package/lib/typescript/dates/internal/brand.d.ts.map +1 -0
  295. package/lib/typescript/dates/internal/calendarHelpers.d.ts +8 -0
  296. package/lib/typescript/dates/internal/calendarHelpers.d.ts.map +1 -0
  297. package/lib/typescript/dates/internal/clampHelpers.d.ts +5 -0
  298. package/lib/typescript/dates/internal/clampHelpers.d.ts.map +1 -0
  299. package/lib/typescript/dates/internal/dateIdToNativeDate.d.ts +12 -0
  300. package/lib/typescript/dates/internal/dateIdToNativeDate.d.ts.map +1 -0
  301. package/lib/typescript/dates/internal/intlCache.d.ts +12 -0
  302. package/lib/typescript/dates/internal/intlCache.d.ts.map +1 -0
  303. package/lib/typescript/dates/internal/intlCopy.d.ts +10 -0
  304. package/lib/typescript/dates/internal/intlCopy.d.ts.map +1 -0
  305. package/lib/typescript/dates/internal/segmentBuilders.d.ts +12 -0
  306. package/lib/typescript/dates/internal/segmentBuilders.d.ts.map +1 -0
  307. package/lib/typescript/dates/labels/dateComponentLabels.d.ts +31 -0
  308. package/lib/typescript/dates/labels/dateComponentLabels.d.ts.map +1 -0
  309. package/lib/typescript/dates/ranges/compareDateIds.d.ts +10 -0
  310. package/lib/typescript/dates/ranges/compareDateIds.d.ts.map +1 -0
  311. package/lib/typescript/dates/ranges/compareMonthIds.d.ts +10 -0
  312. package/lib/typescript/dates/ranges/compareMonthIds.d.ts.map +1 -0
  313. package/lib/typescript/dates/ranges/dateRangeAroundDay.d.ts +14 -0
  314. package/lib/typescript/dates/ranges/dateRangeAroundDay.d.ts.map +1 -0
  315. package/lib/typescript/dates/ranges/dateRangeFromLastNDays.d.ts +16 -0
  316. package/lib/typescript/dates/ranges/dateRangeFromLastNDays.d.ts.map +1 -0
  317. package/lib/typescript/dates/ranges/eachDateIdInRange.d.ts +10 -0
  318. package/lib/typescript/dates/ranges/eachDateIdInRange.d.ts.map +1 -0
  319. package/lib/typescript/dates/ranges/normalizeDateRange.d.ts +15 -0
  320. package/lib/typescript/dates/ranges/normalizeDateRange.d.ts.map +1 -0
  321. package/lib/typescript/dates/segments/applyDateSegmentChange.d.ts +21 -0
  322. package/lib/typescript/dates/segments/applyDateSegmentChange.d.ts.map +1 -0
  323. package/lib/typescript/dates/segments/formatDateSegment.d.ts +13 -0
  324. package/lib/typescript/dates/segments/formatDateSegment.d.ts.map +1 -0
  325. package/lib/typescript/dates/segments/getDateFieldSegments.d.ts +13 -0
  326. package/lib/typescript/dates/segments/getDateFieldSegments.d.ts.map +1 -0
  327. package/lib/typescript/dates/segments/getDateTimeFieldSegments.d.ts +14 -0
  328. package/lib/typescript/dates/segments/getDateTimeFieldSegments.d.ts.map +1 -0
  329. package/lib/typescript/dates/segments/getDateTimeSegmentVisibility.d.ts +8 -0
  330. package/lib/typescript/dates/segments/getDateTimeSegmentVisibility.d.ts.map +1 -0
  331. package/lib/typescript/dates/segments/getEmptyDateSegmentText.d.ts +9 -0
  332. package/lib/typescript/dates/segments/getEmptyDateSegmentText.d.ts.map +1 -0
  333. package/lib/typescript/dates/segments/parseDateSegment.d.ts +13 -0
  334. package/lib/typescript/dates/segments/parseDateSegment.d.ts.map +1 -0
  335. package/lib/typescript/dates/types.d.ts +66 -0
  336. package/lib/typescript/dates/types.d.ts.map +1 -0
  337. package/lib/typescript/dates/wire/clampDateParts.d.ts +12 -0
  338. package/lib/typescript/dates/wire/clampDateParts.d.ts.map +1 -0
  339. package/lib/typescript/dates/wire/clampMonthParts.d.ts +12 -0
  340. package/lib/typescript/dates/wire/clampMonthParts.d.ts.map +1 -0
  341. package/lib/typescript/dates/wire/dateId.d.ts +24 -0
  342. package/lib/typescript/dates/wire/dateId.d.ts.map +1 -0
  343. package/lib/typescript/dates/wire/formatDateId.d.ts +12 -0
  344. package/lib/typescript/dates/wire/formatDateId.d.ts.map +1 -0
  345. package/lib/typescript/dates/wire/formatMonthId.d.ts +12 -0
  346. package/lib/typescript/dates/wire/formatMonthId.d.ts.map +1 -0
  347. package/lib/typescript/dates/wire/isValidDateId.d.ts +13 -0
  348. package/lib/typescript/dates/wire/isValidDateId.d.ts.map +1 -0
  349. package/lib/typescript/dates/wire/isValidDateParts.d.ts +9 -0
  350. package/lib/typescript/dates/wire/isValidDateParts.d.ts.map +1 -0
  351. package/lib/typescript/dates/wire/isValidMonthId.d.ts +13 -0
  352. package/lib/typescript/dates/wire/isValidMonthId.d.ts.map +1 -0
  353. package/lib/typescript/dates/wire/isValidMonthParts.d.ts +9 -0
  354. package/lib/typescript/dates/wire/isValidMonthParts.d.ts.map +1 -0
  355. package/lib/typescript/dates/wire/monthId.d.ts +22 -0
  356. package/lib/typescript/dates/wire/monthId.d.ts.map +1 -0
  357. package/lib/typescript/dates/wire/parseDateId.d.ts +12 -0
  358. package/lib/typescript/dates/wire/parseDateId.d.ts.map +1 -0
  359. package/lib/typescript/dates/wire/parseMonthId.d.ts +12 -0
  360. package/lib/typescript/dates/wire/parseMonthId.d.ts.map +1 -0
  361. package/lib/typescript/dates/wire/toMonthId.d.ts +12 -0
  362. package/lib/typescript/dates/wire/toMonthId.d.ts.map +1 -0
  363. package/lib/typescript/dates/wire/todayDateId.d.ts +8 -0
  364. package/lib/typescript/dates/wire/todayDateId.d.ts.map +1 -0
  365. package/lib/typescript/dates/wire/todayMonthId.d.ts +8 -0
  366. package/lib/typescript/dates/wire/todayMonthId.d.ts.map +1 -0
  367. package/lib/typescript/formatNumber.d.ts +19 -0
  368. package/lib/typescript/formatNumber.d.ts.map +1 -0
  369. package/lib/typescript/index.d.ts +5 -0
  370. package/lib/typescript/index.d.ts.map +1 -0
  371. package/lib/typescript/types.d.ts +2 -0
  372. package/lib/typescript/types.d.ts.map +1 -0
  373. package/lib/typescript/utils.d.ts +10 -0
  374. package/lib/typescript/utils.d.ts.map +1 -0
  375. package/package.json +50 -0
  376. package/src/__tests__/applyDateSegmentChange.test.ts +26 -0
  377. package/src/__tests__/calendarFormatters.test.ts +35 -0
  378. package/src/__tests__/clampDateParts.test.ts +16 -0
  379. package/src/__tests__/compareDateIds.test.ts +7 -0
  380. package/src/__tests__/compareMonthIds.test.ts +19 -0
  381. package/src/__tests__/dateComponentLabels.test.ts +25 -0
  382. package/src/__tests__/dateRangeAroundDay.test.ts +10 -0
  383. package/src/__tests__/dateRangeFromLastNDays.test.ts +8 -0
  384. package/src/__tests__/dateSegmentHelpers.test.ts +24 -0
  385. package/src/__tests__/datetimeHelpers.test.ts +65 -0
  386. package/src/__tests__/displayFormatters.test.ts +34 -0
  387. package/src/__tests__/eachDateIdInRange.test.ts +11 -0
  388. package/src/__tests__/formatCalendarMonthYear.test.ts +9 -0
  389. package/src/__tests__/formatDateForDisplay.test.ts +11 -0
  390. package/src/__tests__/formatDateId.test.ts +15 -0
  391. package/src/__tests__/formatMonthId.test.ts +7 -0
  392. package/src/__tests__/formatNumber.test.ts +35 -0
  393. package/src/__tests__/getDateFieldSegments.test.ts +35 -0
  394. package/src/__tests__/getDateTimeFieldSegments.test.ts +140 -0
  395. package/src/__tests__/getDateTimeSegmentVisibility.test.ts +12 -0
  396. package/src/__tests__/intlCopy.test.ts +64 -0
  397. package/src/__tests__/isValidDateId.test.ts +8 -0
  398. package/src/__tests__/isValidMonthId.test.ts +8 -0
  399. package/src/__tests__/normalizeDateRange.test.ts +10 -0
  400. package/src/__tests__/toMonthId.test.ts +7 -0
  401. package/src/__tests__/todayDateId.test.ts +7 -0
  402. package/src/__tests__/wireConstructors.test.ts +74 -0
  403. package/src/dates/calendar/formatCalendarMonthYear.ts +21 -0
  404. package/src/dates/calendar/formatDateTimeListDateRow.ts +41 -0
  405. package/src/dates/calendar/formatMonthCalendarMonth.ts +21 -0
  406. package/src/dates/calendar/formatMonthCalendarYear.ts +9 -0
  407. package/src/dates/calendar/getCalendarWeekdayLabels.ts +23 -0
  408. package/src/dates/datetime/clampDateTimeId.ts +25 -0
  409. package/src/dates/datetime/compareDateTimeIds.ts +23 -0
  410. package/src/dates/datetime/dateTimeId.ts +36 -0
  411. package/src/dates/datetime/formatDateTimeId.ts +35 -0
  412. package/src/dates/datetime/formatDateTimeListHour.ts +14 -0
  413. package/src/dates/datetime/formatDateTimeListMinute.ts +9 -0
  414. package/src/dates/datetime/formatDateTimeListPeriod.ts +12 -0
  415. package/src/dates/datetime/isLocaleHour12.ts +23 -0
  416. package/src/dates/datetime/isValidDateTimeId.ts +18 -0
  417. package/src/dates/datetime/nowDateTimeId.ts +53 -0
  418. package/src/dates/datetime/parseDateTimeId.ts +24 -0
  419. package/src/dates/display/formatDateForDisplay.ts +21 -0
  420. package/src/dates/display/formatDateRangeForDisplay.ts +23 -0
  421. package/src/dates/display/formatDateTimeForDisplay.ts +37 -0
  422. package/src/dates/display/formatMonthForDisplay.ts +26 -0
  423. package/src/dates/index.ts +86 -0
  424. package/src/dates/internal/brand.ts +11 -0
  425. package/src/dates/internal/calendarHelpers.ts +18 -0
  426. package/src/dates/internal/clampHelpers.ts +15 -0
  427. package/src/dates/internal/dateIdToNativeDate.ts +15 -0
  428. package/src/dates/internal/intlCache.ts +40 -0
  429. package/src/dates/internal/intlCopy.ts +75 -0
  430. package/src/dates/internal/segmentBuilders.ts +94 -0
  431. package/src/dates/labels/dateComponentLabels.ts +79 -0
  432. package/src/dates/ranges/compareDateIds.ts +21 -0
  433. package/src/dates/ranges/compareMonthIds.ts +26 -0
  434. package/src/dates/ranges/dateRangeAroundDay.ts +24 -0
  435. package/src/dates/ranges/dateRangeFromLastNDays.ts +26 -0
  436. package/src/dates/ranges/eachDateIdInRange.ts +21 -0
  437. package/src/dates/ranges/normalizeDateRange.ts +18 -0
  438. package/src/dates/segments/applyDateSegmentChange.ts +57 -0
  439. package/src/dates/segments/formatDateSegment.ts +18 -0
  440. package/src/dates/segments/getDateFieldSegments.ts +45 -0
  441. package/src/dates/segments/getDateTimeFieldSegments.ts +126 -0
  442. package/src/dates/segments/getDateTimeSegmentVisibility.ts +14 -0
  443. package/src/dates/segments/getEmptyDateSegmentText.ts +12 -0
  444. package/src/dates/segments/parseDateSegment.ts +25 -0
  445. package/src/dates/types.ts +80 -0
  446. package/src/dates/wire/clampDateParts.ts +17 -0
  447. package/src/dates/wire/clampMonthParts.ts +15 -0
  448. package/src/dates/wire/dateId.ts +44 -0
  449. package/src/dates/wire/formatDateId.ts +20 -0
  450. package/src/dates/wire/formatMonthId.ts +16 -0
  451. package/src/dates/wire/isValidDateId.ts +22 -0
  452. package/src/dates/wire/isValidDateParts.ts +17 -0
  453. package/src/dates/wire/isValidMonthId.ts +22 -0
  454. package/src/dates/wire/isValidMonthParts.ts +11 -0
  455. package/src/dates/wire/monthId.ts +42 -0
  456. package/src/dates/wire/parseDateId.ts +20 -0
  457. package/src/dates/wire/parseMonthId.ts +20 -0
  458. package/src/dates/wire/toMonthId.ts +17 -0
  459. package/src/dates/wire/todayDateId.ts +12 -0
  460. package/src/dates/wire/todayMonthId.ts +12 -0
  461. package/src/formatNumber.ts +56 -0
  462. package/src/index.ts +82 -0
  463. package/src/types.ts +1 -0
  464. package/src/utils.ts +29 -0
@@ -0,0 +1,140 @@
1
+ import { getDateTimeFieldSegments } from '../dates/segments/getDateTimeFieldSegments';
2
+
3
+ describe('getDateTimeFieldSegments', () => {
4
+ it('returns placeholder date-time segments when value is empty', () => {
5
+ const segments = getDateTimeFieldSegments(undefined, {
6
+ granularity: 'minute',
7
+ locale: 'en-US',
8
+ hour12: true,
9
+ });
10
+ expect(segments.find((s) => s.type === 'month')?.text).toBe('MM');
11
+ expect(segments.find((s) => s.type === 'hour')?.text).toBe('hh');
12
+ expect(segments.find((s) => s.type === 'hour')?.value).toBeUndefined();
13
+ expect(segments.find((s) => s.type === 'minute')?.text).toBe('mm');
14
+ expect(segments.find((s) => s.type === 'dayPeriod')?.text).toBe('AM');
15
+ });
16
+
17
+ it('returns 12-hour date-time field segments with day period', () => {
18
+ const segments = getDateTimeFieldSegments('2026-07-28T14:30', {
19
+ granularity: 'minute',
20
+ locale: 'en-US',
21
+ hour12: true,
22
+ });
23
+ expect(segments.map((s) => s.type)).toEqual([
24
+ 'month',
25
+ 'literal',
26
+ 'day',
27
+ 'literal',
28
+ 'year',
29
+ 'literal',
30
+ 'hour',
31
+ 'literal',
32
+ 'minute',
33
+ 'literal',
34
+ 'dayPeriod',
35
+ ]);
36
+ expect(segments.find((s) => s.type === 'hour')?.text).toBe('2');
37
+ expect(segments.find((s) => s.type === 'dayPeriod')?.text).toBe('PM');
38
+ });
39
+
40
+ it('returns 24-hour date-time field segments without day period', () => {
41
+ const segments = getDateTimeFieldSegments('2026-07-28T14:30', {
42
+ granularity: 'minute',
43
+ locale: 'en-US',
44
+ hour12: false,
45
+ });
46
+ expect(segments.map((s) => s.type)).toEqual([
47
+ 'month',
48
+ 'literal',
49
+ 'day',
50
+ 'literal',
51
+ 'year',
52
+ 'literal',
53
+ 'hour',
54
+ 'literal',
55
+ 'minute',
56
+ ]);
57
+ expect(segments.find((s) => s.type === 'hour')?.text).toBe('14');
58
+ expect(segments.find((s) => s.type === 'dayPeriod')).toBeUndefined();
59
+ });
60
+
61
+ it('omits minute and second segments at hour granularity', () => {
62
+ const segments = getDateTimeFieldSegments('2026-07-28T14:30', {
63
+ granularity: 'hour',
64
+ locale: 'en-US',
65
+ hour12: true,
66
+ });
67
+ expect(segments.map((s) => s.type)).toEqual([
68
+ 'month',
69
+ 'literal',
70
+ 'day',
71
+ 'literal',
72
+ 'year',
73
+ 'literal',
74
+ 'hour',
75
+ 'literal',
76
+ 'dayPeriod',
77
+ ]);
78
+ expect(segments.some((s) => s.type === 'minute')).toBe(false);
79
+ expect(segments.some((s) => s.type === 'second')).toBe(false);
80
+ });
81
+
82
+ it('places the second segment before the day period at second granularity', () => {
83
+ const segments = getDateTimeFieldSegments('2026-07-28T14:30:45', {
84
+ granularity: 'second',
85
+ locale: 'en-US',
86
+ hour12: true,
87
+ });
88
+ expect(segments.map((s) => s.type)).toEqual([
89
+ 'month',
90
+ 'literal',
91
+ 'day',
92
+ 'literal',
93
+ 'year',
94
+ 'literal',
95
+ 'hour',
96
+ 'literal',
97
+ 'minute',
98
+ 'literal',
99
+ 'second',
100
+ 'literal',
101
+ 'dayPeriod',
102
+ ]);
103
+ expect(segments.find((s) => s.type === 'second')?.text).toBe('45');
104
+ expect(segments.find((s) => s.type === 'dayPeriod')?.text).toBe('PM');
105
+ });
106
+
107
+ it('places the second segment last on a 24-hour clock at second granularity', () => {
108
+ const segments = getDateTimeFieldSegments('2026-07-28T14:30:45', {
109
+ granularity: 'second',
110
+ locale: 'en-US',
111
+ hour12: false,
112
+ });
113
+ expect(segments.map((s) => s.type)).toEqual([
114
+ 'month',
115
+ 'literal',
116
+ 'day',
117
+ 'literal',
118
+ 'year',
119
+ 'literal',
120
+ 'hour',
121
+ 'literal',
122
+ 'minute',
123
+ 'literal',
124
+ 'second',
125
+ ]);
126
+ expect(segments.find((s) => s.type === 'second')?.text).toBe('45');
127
+ });
128
+
129
+ it('orders empty placeholder second before the day period', () => {
130
+ const segments = getDateTimeFieldSegments(undefined, {
131
+ granularity: 'second',
132
+ locale: 'en-US',
133
+ hour12: true,
134
+ });
135
+ const secondIndex = segments.findIndex((s) => s.type === 'second');
136
+ const dayPeriodIndex = segments.findIndex((s) => s.type === 'dayPeriod');
137
+ expect(secondIndex).toBeGreaterThanOrEqual(0);
138
+ expect(dayPeriodIndex).toBeGreaterThan(secondIndex);
139
+ });
140
+ });
@@ -0,0 +1,12 @@
1
+ import { getDateTimeSegmentVisibility } from '../dates/segments/getDateTimeSegmentVisibility';
2
+
3
+ describe('getDateTimeSegmentVisibility', () => {
4
+ it.each([
5
+ ['day', { showTime: false, showMinute: false, showSecond: false }],
6
+ ['hour', { showTime: true, showMinute: false, showSecond: false }],
7
+ ['minute', { showTime: true, showMinute: true, showSecond: false }],
8
+ ['second', { showTime: true, showMinute: true, showSecond: true }],
9
+ ] as const)('matches DateTimeList columns at %s granularity', (granularity, expected) => {
10
+ expect(getDateTimeSegmentVisibility(granularity)).toEqual(expected);
11
+ });
12
+ });
@@ -0,0 +1,64 @@
1
+ import {
2
+ formatDayPeriodFromHour,
3
+ formatRelativeToday,
4
+ getDateRangeSeparator,
5
+ } from '../dates/internal/intlCopy';
6
+
7
+ describe('intlCopy', () => {
8
+ describe('formatRelativeToday', () => {
9
+ it('returns a locale-aware today label', () => {
10
+ expect(formatRelativeToday('en-US')).toBeTruthy();
11
+ });
12
+
13
+ it('falls back to Today when RelativeTimeFormat is unavailable', () => {
14
+ const original = Intl.RelativeTimeFormat;
15
+ // @ts-expect-error — simulate missing API
16
+ Intl.RelativeTimeFormat = undefined;
17
+ expect(formatRelativeToday('en-US')).toBe('Today');
18
+ Intl.RelativeTimeFormat = original;
19
+ });
20
+ });
21
+
22
+ describe('formatDayPeriodFromHour', () => {
23
+ it('returns AM for morning hours', () => {
24
+ expect(formatDayPeriodFromHour(9, 'en-US')).toMatch(/AM/i);
25
+ });
26
+
27
+ it('returns PM for afternoon hours', () => {
28
+ expect(formatDayPeriodFromHour(15, 'en-US')).toMatch(/PM/i);
29
+ });
30
+
31
+ it('falls back when formatToParts is unavailable', () => {
32
+ const prototype = Intl.DateTimeFormat.prototype;
33
+ const descriptor = Object.getOwnPropertyDescriptor(prototype, 'formatToParts');
34
+ Reflect.deleteProperty(prototype, 'formatToParts');
35
+ try {
36
+ expect(formatDayPeriodFromHour(9, 'en-US')).toBe('AM');
37
+ } finally {
38
+ if (descriptor) {
39
+ Object.defineProperty(prototype, 'formatToParts', descriptor);
40
+ }
41
+ }
42
+ });
43
+ });
44
+
45
+ describe('getDateRangeSeparator', () => {
46
+ it('returns a separator between formatted dates', () => {
47
+ const separator = getDateRangeSeparator('en-US');
48
+ expect(separator.trim().length).toBeGreaterThan(0);
49
+ });
50
+
51
+ it('falls back to en dash when formatRangeToParts is unavailable', () => {
52
+ const prototype = Intl.DateTimeFormat.prototype;
53
+ const descriptor = Object.getOwnPropertyDescriptor(prototype, 'formatRangeToParts');
54
+ Reflect.deleteProperty(prototype, 'formatRangeToParts');
55
+ try {
56
+ expect(getDateRangeSeparator('en-US')).toBe(' – ');
57
+ } finally {
58
+ if (descriptor) {
59
+ Object.defineProperty(prototype, 'formatRangeToParts', descriptor);
60
+ }
61
+ }
62
+ });
63
+ });
64
+ });
@@ -0,0 +1,8 @@
1
+ import { isValidDateId } from '../dates/wire/isValidDateId';
2
+
3
+ describe('isValidDateId', () => {
4
+ it('rejects invalid DateId', () => {
5
+ expect(isValidDateId('2026-13-01')).toBe(false);
6
+ expect(isValidDateId('07/28/2026')).toBe(false);
7
+ });
8
+ });
@@ -0,0 +1,8 @@
1
+ import { isValidMonthId } from '../dates/wire/isValidMonthId';
2
+
3
+ describe('isValidMonthId', () => {
4
+ it('validates MonthId day is 01', () => {
5
+ expect(isValidMonthId('2026-07-01')).toBe(true);
6
+ expect(isValidMonthId('2026-07-15')).toBe(false);
7
+ });
8
+ });
@@ -0,0 +1,10 @@
1
+ import { normalizeDateRange } from '../dates/ranges/normalizeDateRange';
2
+
3
+ describe('normalizeDateRange', () => {
4
+ it('normalizes inverted range', () => {
5
+ expect(normalizeDateRange({ startId: '2026-07-28', endId: '2026-07-01' })).toEqual({
6
+ startId: '2026-07-01',
7
+ endId: '2026-07-28',
8
+ });
9
+ });
10
+ });
@@ -0,0 +1,7 @@
1
+ import { toMonthId } from '../dates/wire/toMonthId';
2
+
3
+ describe('toMonthId', () => {
4
+ it('converts to month id', () => {
5
+ expect(toMonthId('2026-07-28')).toBe('2026-07-01');
6
+ });
7
+ });
@@ -0,0 +1,7 @@
1
+ import { todayDateId } from '../dates/wire/todayDateId';
2
+
3
+ describe('todayDateId', () => {
4
+ it('returns todayDateId in YYYY-MM-DD shape', () => {
5
+ expect(todayDateId()).toMatch(/^\d{4}-\d{2}-\d{2}$/);
6
+ });
7
+ });
@@ -0,0 +1,74 @@
1
+ import { dateId } from '../dates/wire/dateId';
2
+ import { monthId } from '../dates/wire/monthId';
3
+ import { dateTimeId } from '../dates/datetime/dateTimeId';
4
+ import { isValidDateParts } from '../dates/wire/isValidDateParts';
5
+ import { isValidMonthParts } from '../dates/wire/isValidMonthParts';
6
+
7
+ describe('wire constructors', () => {
8
+ describe('dateId', () => {
9
+ it('accepts valid wire strings', () => {
10
+ expect(dateId('2026-07-28')).toBe('2026-07-28');
11
+ });
12
+
13
+ it('builds from numeric parts', () => {
14
+ expect(dateId(2026, 7, 28)).toBe('2026-07-28');
15
+ });
16
+
17
+ it('throws on invalid wire strings', () => {
18
+ expect(() => dateId('2026-13-01')).toThrow(RangeError);
19
+ });
20
+
21
+ it('throws on invalid parts', () => {
22
+ expect(() => dateId(2026, 13, 1)).toThrow(RangeError);
23
+ });
24
+ });
25
+
26
+ describe('monthId', () => {
27
+ it('accepts valid wire strings', () => {
28
+ expect(monthId('2026-07-01')).toBe('2026-07-01');
29
+ });
30
+
31
+ it('builds from numeric parts', () => {
32
+ expect(monthId(2026, 7)).toBe('2026-07-01');
33
+ });
34
+
35
+ it('throws on invalid wire strings', () => {
36
+ expect(() => monthId('2026-07-15')).toThrow(RangeError);
37
+ });
38
+
39
+ it('throws on invalid parts', () => {
40
+ expect(() => monthId(2026, 13)).toThrow(RangeError);
41
+ });
42
+ });
43
+
44
+ describe('dateTimeId', () => {
45
+ it('accepts valid wire strings', () => {
46
+ expect(dateTimeId('2026-07-28T10:01')).toBe('2026-07-28T10:01');
47
+ });
48
+
49
+ it('builds from parts', () => {
50
+ expect(dateTimeId({ year: 2026, month: 7, day: 28, hour: 10, minute: 1 })).toBe(
51
+ '2026-07-28T10:01',
52
+ );
53
+ });
54
+
55
+ it('throws on invalid wire strings', () => {
56
+ expect(() => dateTimeId('not-a-date')).toThrow(RangeError);
57
+ });
58
+ });
59
+
60
+ describe('isValidDateParts', () => {
61
+ it('validates real calendar dates', () => {
62
+ expect(isValidDateParts({ year: 2026, month: 7, day: 28 })).toBe(true);
63
+ expect(isValidDateParts({ year: 2026, month: 2, day: 30 })).toBe(false);
64
+ });
65
+ });
66
+
67
+ describe('isValidMonthParts', () => {
68
+ it('validates month range', () => {
69
+ expect(isValidMonthParts({ year: 2026, month: 7 })).toBe(true);
70
+ expect(isValidMonthParts({ year: 2026, month: 0 })).toBe(false);
71
+ expect(isValidMonthParts({ year: 2026, month: 13 })).toBe(false);
72
+ });
73
+ });
74
+ });
@@ -0,0 +1,21 @@
1
+ import { dateIdToNativeDate } from '../internal/dateIdToNativeDate';
2
+ import { getCachedDateFormatter } from '../internal/intlCache';
3
+ import type { DateFormatOptions, MonthId } from '../types';
4
+
5
+ /**
6
+ * Formats a calendar header label, e.g. `July 2026`.
7
+ *
8
+ * Uses `Intl` so `options.locale` is respected (same pattern as display formatters).
9
+ *
10
+ * @param monthId - Wire month string (`YYYY-MM-01`).
11
+ * @param options - Locale and optional time zone.
12
+ * @returns Long month and year label.
13
+ */
14
+ export function formatCalendarMonthYear(monthId: MonthId, options?: DateFormatOptions): string {
15
+ const formatter = getCachedDateFormatter(options?.locale ?? 'en-US', {
16
+ month: 'long',
17
+ year: 'numeric',
18
+ ...(options?.timeZone ? { timeZone: options.timeZone } : {}),
19
+ });
20
+ return formatter.format(dateIdToNativeDate(monthId));
21
+ }
@@ -0,0 +1,41 @@
1
+ import { dateIdToNativeDate } from '../internal/dateIdToNativeDate';
2
+ import { formatRelativeToday } from '../internal/intlCopy';
3
+ import { getCachedDateFormatter } from '../internal/intlCache';
4
+ import type { DateFormatOptions, DateId } from '../types';
5
+
6
+ /**
7
+ * Formats a row label for a scrollable date list. Returns a locale-aware "today" label when the
8
+ * id matches today (pass a precomputed `todayDateId` when comparing wire ids).
9
+ *
10
+ * @param dateId - Wire date string.
11
+ * @param options - Locale, optional `todayDateId` override, and time zone.
12
+ * @returns Relative today label or a short weekday/month/day label.
13
+ */
14
+ export function formatDateTimeListDateRow(
15
+ dateId: DateId,
16
+ options?: DateFormatOptions & { todayDateId?: DateId },
17
+ ): string {
18
+ const locale = options?.locale ?? 'en-US';
19
+ const todayId = options?.todayDateId;
20
+ if (todayId && dateId === todayId) {
21
+ return formatRelativeToday(locale);
22
+ }
23
+
24
+ const date = dateIdToNativeDate(dateId);
25
+ const todayParts = new Date();
26
+ const isToday =
27
+ date.getFullYear() === todayParts.getFullYear() &&
28
+ date.getMonth() === todayParts.getMonth() &&
29
+ date.getDate() === todayParts.getDate();
30
+ if (isToday) {
31
+ return formatRelativeToday(locale);
32
+ }
33
+
34
+ const formatter = getCachedDateFormatter(locale, {
35
+ weekday: 'short',
36
+ month: 'short',
37
+ day: 'numeric',
38
+ ...(options?.timeZone ? { timeZone: options.timeZone } : {}),
39
+ });
40
+ return formatter.format(date);
41
+ }
@@ -0,0 +1,21 @@
1
+ import { getCachedDateFormatter } from '../internal/intlCache';
2
+ import type { DateFormatOptions } from '../types';
3
+
4
+ /**
5
+ * Formats a short month name for month-grid cells (1–12).
6
+ *
7
+ * @param month - Month number (1–12).
8
+ * @param options - Locale and optional time zone.
9
+ * @returns Short month name.
10
+ *
11
+ * @example
12
+ * formatMonthCalendarMonth(7, { locale: 'en-US' }) // 'Jul'
13
+ */
14
+ export function formatMonthCalendarMonth(month: number, options?: DateFormatOptions): string {
15
+ const date = new Date(2024, month - 1, 1);
16
+ const formatter = getCachedDateFormatter(options?.locale ?? 'en-US', {
17
+ month: 'short',
18
+ ...(options?.timeZone ? { timeZone: options.timeZone } : {}),
19
+ });
20
+ return formatter.format(date);
21
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Formats a year label for month-calendar decade/year pickers.
3
+ *
4
+ * @param year - Four-digit year.
5
+ * @returns Year as a string.
6
+ */
7
+ export function formatMonthCalendarYear(year: number): string {
8
+ return String(year);
9
+ }
@@ -0,0 +1,23 @@
1
+ import { formatCalendarWeekday } from '../internal/calendarHelpers';
2
+ import type { DateFormatOptions } from '../types';
3
+
4
+ /**
5
+ * Returns ordered weekday labels for a calendar week header.
6
+ *
7
+ * @param options - Locale, first day of week, and weekday width.
8
+ * @returns Array of seven weekday label strings.
9
+ */
10
+ export function getCalendarWeekdayLabels(
11
+ options?: DateFormatOptions & {
12
+ firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
13
+ weekday?: 'short' | 'narrow' | 'long';
14
+ },
15
+ ): string[] {
16
+ const firstDayOfWeek = options?.firstDayOfWeek ?? 0;
17
+ const labels: string[] = [];
18
+ for (let i = 0; i < 7; i += 1) {
19
+ const index = (firstDayOfWeek + i) % 7;
20
+ labels.push(formatCalendarWeekday(index, options));
21
+ }
22
+ return labels;
23
+ }
@@ -0,0 +1,25 @@
1
+ import type { DateTimeId } from '../types';
2
+ import { compareDateTimeIds } from './compareDateTimeIds';
3
+
4
+ /**
5
+ * Clamps a wire date-time into the inclusive `[min, max]` range.
6
+ *
7
+ * Returns `min` when `value` is earlier than `min`, `max` when later than `max`,
8
+ * otherwise `value` unchanged. Omitted bounds are ignored.
9
+ *
10
+ * @param value - Wire date-time to clamp.
11
+ * @param bounds - Optional inclusive `min` / `max` wire date-times.
12
+ * @returns The clamped `DateTimeId`.
13
+ */
14
+ export function clampDateTimeId(
15
+ value: DateTimeId,
16
+ bounds: { min?: DateTimeId; max?: DateTimeId },
17
+ ): DateTimeId {
18
+ if (bounds.min && compareDateTimeIds(value, bounds.min) < 0) {
19
+ return bounds.min;
20
+ }
21
+ if (bounds.max && compareDateTimeIds(value, bounds.max) > 0) {
22
+ return bounds.max;
23
+ }
24
+ return value;
25
+ }
@@ -0,0 +1,23 @@
1
+ import { compareAsc, parseISO } from 'date-fns';
2
+ import type { DateTimeId } from '../types';
3
+
4
+ /**
5
+ * Compares two wire date-times chronologically.
6
+ *
7
+ * Handles local (`YYYY-MM-DDTHH:MM`) and UTC (`…Z`) forms alike by parsing each
8
+ * to an absolute instant before comparing.
9
+ *
10
+ * @param a - First wire date-time.
11
+ * @param b - Second wire date-time.
12
+ * @returns `-1` if `a` is earlier, `1` if later, `0` if equal.
13
+ */
14
+ export function compareDateTimeIds(a: DateTimeId, b: DateTimeId): -1 | 0 | 1 {
15
+ const result = compareAsc(parseISO(a), parseISO(b));
16
+ if (result < 0) {
17
+ return -1;
18
+ }
19
+ if (result > 0) {
20
+ return 1;
21
+ }
22
+ return 0;
23
+ }
@@ -0,0 +1,36 @@
1
+ import { asDateTimeId } from '../internal/brand';
2
+ import type { DateTimeId, DateTimeParts } from '../types';
3
+ import { formatDateTimeId } from './formatDateTimeId';
4
+ import { isValidDateTimeId } from './isValidDateTimeId';
5
+
6
+ /**
7
+ * Validating smart constructor for a wire {@link DateTimeId} (local ISO-like,
8
+ * e.g. `YYYY-MM-DDTHH:mm`).
9
+ *
10
+ * Accepts either a wire string or {@link DateTimeParts}. Throws `RangeError` on
11
+ * input that does not parse to a valid date-time.
12
+ *
13
+ * @param input - A wire date-time string or {@link DateTimeParts}.
14
+ * @returns The branded `DateTimeId`.
15
+ * @throws RangeError when the input is not a valid `DateTimeId`.
16
+ *
17
+ * @example
18
+ * dateTimeId('2026-08-07T14:30'); // DateTimeId
19
+ * dateTimeId({ year: 2026, month: 8, day: 7, hour: 14, minute: 30 }); // DateTimeId
20
+ */
21
+ export function dateTimeId(input: string | DateTimeParts): DateTimeId {
22
+ if (typeof input === 'string') {
23
+ if (!isValidDateTimeId(input)) {
24
+ throw new RangeError(
25
+ `Invalid DateTimeId: "${input}". Expected a wire date-time such as "YYYY-MM-DDTHH:mm".`,
26
+ );
27
+ }
28
+ return input;
29
+ }
30
+
31
+ const built = formatDateTimeId(input);
32
+ if (!isValidDateTimeId(built)) {
33
+ throw new RangeError(`Invalid DateTimeId parts: ${JSON.stringify(input)}.`);
34
+ }
35
+ return asDateTimeId(built);
36
+ }
@@ -0,0 +1,35 @@
1
+ import { asDateTimeId } from '../internal/brand';
2
+ import { formatDateId } from '../wire/formatDateId';
3
+ import type { DateTimeId, DateTimeParts } from '../types';
4
+
5
+ /**
6
+ * Builds a wire `DateTimeId` from parts. Local by default; pass `{ utc: true }` for ISO UTC.
7
+ *
8
+ * @param parts - Date and time parts.
9
+ * @param options - When `utc` is true, returns an ISO UTC string ending in `Z`.
10
+ * @returns Wire `DateTimeId` string.
11
+ */
12
+ export function formatDateTimeId(parts: DateTimeParts, options?: { utc?: boolean }): DateTimeId {
13
+ const date = options?.utc
14
+ ? new Date(
15
+ Date.UTC(
16
+ parts.year,
17
+ parts.month - 1,
18
+ parts.day,
19
+ parts.hour,
20
+ parts.minute,
21
+ parts.second ?? 0,
22
+ ),
23
+ )
24
+ : new Date(parts.year, parts.month - 1, parts.day, parts.hour, parts.minute, parts.second ?? 0);
25
+
26
+ if (options?.utc) {
27
+ return asDateTimeId(date.toISOString());
28
+ }
29
+
30
+ const datePart = formatDateId(parts);
31
+ const hour = String(parts.hour).padStart(2, '0');
32
+ const minute = String(parts.minute).padStart(2, '0');
33
+ const second = parts.second != null ? `:${String(parts.second).padStart(2, '0')}` : '';
34
+ return asDateTimeId(`${datePart}T${hour}:${minute}${second}`);
35
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Formats the hour label for a date-time list column.
3
+ *
4
+ * @param hour - Hour value (0–23).
5
+ * @param options - When `hour12` is true, returns 1–12 without leading zero.
6
+ * @returns Hour label string.
7
+ */
8
+ export function formatDateTimeListHour(hour: number, options?: { hour12?: boolean }): string {
9
+ if (options?.hour12) {
10
+ const h = hour % 12 || 12;
11
+ return String(h);
12
+ }
13
+ return String(hour).padStart(2, '0');
14
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Formats a zero-padded minute label for a date-time list column.
3
+ *
4
+ * @param minute - Minute value (0–59).
5
+ * @returns Two-digit minute string.
6
+ */
7
+ export function formatDateTimeListMinute(minute: number): string {
8
+ return String(minute).padStart(2, '0');
9
+ }
@@ -0,0 +1,12 @@
1
+ import { formatDayPeriodFromHour } from '../internal/intlCopy';
2
+ import type { DateFormatOptions } from '../types';
3
+
4
+ /**
5
+ * Returns the day-period label (AM/PM or locale equivalent) derived from a 0–23 hour value.
6
+ *
7
+ * @param hour - Hour value (0–23).
8
+ * @param options - Locale for the day-period label.
9
+ */
10
+ export function formatDateTimeListPeriod(hour: number, options?: DateFormatOptions): string {
11
+ return formatDayPeriodFromHour(hour, options?.locale);
12
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Whether the given locale conventionally uses a 12-hour clock (AM/PM).
3
+ *
4
+ * Derived from the locale's resolved hour cycle so date-time components can
5
+ * default their clock to the locale instead of hardcoding 12-hour. Pass an
6
+ * explicit `hour12` to override.
7
+ *
8
+ * @param locale - BCP-47 locale. Defaults to `en-US`.
9
+ * @returns `true` when the locale uses a 12-hour clock.
10
+ */
11
+ export function isLocaleHour12(locale?: string): boolean {
12
+ try {
13
+ const resolved = new Intl.DateTimeFormat(locale ?? 'en-US', {
14
+ hour: 'numeric',
15
+ }).resolvedOptions() as { hour12?: boolean; hourCycle?: string };
16
+ if (typeof resolved.hour12 === 'boolean') {
17
+ return resolved.hour12;
18
+ }
19
+ return resolved.hourCycle === 'h11' || resolved.hourCycle === 'h12';
20
+ } catch {
21
+ return true;
22
+ }
23
+ }
@@ -0,0 +1,18 @@
1
+ import { isValid, parseISO } from 'date-fns';
2
+ import type { DateTimeId } from '../types';
3
+
4
+ const LOCAL_DATE_TIME_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?$/;
5
+
6
+ /**
7
+ * Type guard for local `DateTimeId` (`YYYY-MM-DDTHH:mm` or with seconds) and UTC `…Z` strings.
8
+ *
9
+ * @param dateTimeId - Candidate wire date-time string.
10
+ * @returns `true` when `dateTimeId` is a valid `DateTimeId`.
11
+ */
12
+ export function isValidDateTimeId(dateTimeId: string): dateTimeId is DateTimeId {
13
+ if (!LOCAL_DATE_TIME_PATTERN.test(dateTimeId) && !dateTimeId.endsWith('Z')) {
14
+ return false;
15
+ }
16
+ const parsed = parseISO(dateTimeId);
17
+ return isValid(parsed);
18
+ }