@sixthshift/design-system 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +222 -0
  3. package/dist/styles.css +2 -0
  4. package/dist/theme.generated.css +438 -0
  5. package/package.json +238 -0
  6. package/src/components/Avatar/Avatar.tsx +19 -0
  7. package/src/components/Avatar/index.ts +1 -0
  8. package/src/components/Badge/Badge.tsx +59 -0
  9. package/src/components/Badge/index.ts +1 -0
  10. package/src/components/BarChart/BarChart.tsx +51 -0
  11. package/src/components/BarChart/index.ts +1 -0
  12. package/src/components/Breadcrumb/Breadcrumb.tsx +47 -0
  13. package/src/components/Breadcrumb/index.ts +5 -0
  14. package/src/components/Button/Button.tsx +157 -0
  15. package/src/components/Button/index.ts +1 -0
  16. package/src/components/Calendar/Calendar.tsx +433 -0
  17. package/src/components/Calendar/calendar.hooks.ts +329 -0
  18. package/src/components/Calendar/calendar.types.ts +117 -0
  19. package/src/components/Calendar/index.ts +28 -0
  20. package/src/components/Card/Card.tsx +47 -0
  21. package/src/components/Card/index.ts +1 -0
  22. package/src/components/Checkbox/Checkbox.tsx +144 -0
  23. package/src/components/Checkbox/index.ts +1 -0
  24. package/src/components/CheckboxGroup/CheckboxGroup.tsx +173 -0
  25. package/src/components/CheckboxGroup/index.ts +5 -0
  26. package/src/components/Code/Editor/Editor.tsx +161 -0
  27. package/src/components/Code/Editor/index.ts +2 -0
  28. package/src/components/Code/Editor/semanticTokenProvider.ts +69 -0
  29. package/src/components/Code/Editor/themes.ts +112 -0
  30. package/src/components/Code/ValidationStatus/ValidationStatus.tsx +81 -0
  31. package/src/components/Code/ValidationStatus/index.ts +1 -0
  32. package/src/components/Code/Workspace/StatusBar.tsx +47 -0
  33. package/src/components/Code/Workspace/Toolbar.tsx +47 -0
  34. package/src/components/Code/Workspace/Workspace.tsx +109 -0
  35. package/src/components/Code/Workspace/index.ts +3 -0
  36. package/src/components/ColorDot/ColorDot.tsx +50 -0
  37. package/src/components/ColorDot/index.ts +1 -0
  38. package/src/components/DatePicker/DatePicker.tsx +236 -0
  39. package/src/components/DatePicker/datepicker.hooks.ts +381 -0
  40. package/src/components/DatePicker/datepicker.types.ts +140 -0
  41. package/src/components/DatePicker/index.ts +12 -0
  42. package/src/components/DateRangePicker/DateRangePicker.tsx +127 -0
  43. package/src/components/DateRangePicker/daterangepicker.types.ts +53 -0
  44. package/src/components/DateRangePicker/index.ts +2 -0
  45. package/src/components/DateTimePicker/DateTimePicker.tsx +399 -0
  46. package/src/components/DateTimePicker/datetimepicker.types.ts +48 -0
  47. package/src/components/DateTimePicker/index.ts +2 -0
  48. package/src/components/DateTimeRangePicker/DateTimeRangePicker.tsx +679 -0
  49. package/src/components/DateTimeRangePicker/datetimerangepicker.types.ts +62 -0
  50. package/src/components/DateTimeRangePicker/index.ts +2 -0
  51. package/src/components/EmptyState/EmptyState.tsx +29 -0
  52. package/src/components/EmptyState/index.ts +1 -0
  53. package/src/components/Field/Field.tsx +60 -0
  54. package/src/components/Field/index.ts +1 -0
  55. package/src/components/FormField/FormField.tsx +55 -0
  56. package/src/components/FormField/index.ts +2 -0
  57. package/src/components/HeatMap/HeatMapCalendar.tsx +127 -0
  58. package/src/components/HeatMap/HeatMapMatrix.tsx +75 -0
  59. package/src/components/HeatMap/heat-map.utils.ts +15 -0
  60. package/src/components/HeatMap/index.ts +3 -0
  61. package/src/components/HoverCard/HoverCard.tsx +83 -0
  62. package/src/components/HoverCard/components/HoverCardContent.tsx +30 -0
  63. package/src/components/HoverCard/components/HoverCardContext.tsx +22 -0
  64. package/src/components/HoverCard/components/HoverCardTrigger.tsx +32 -0
  65. package/src/components/HoverCard/index.ts +3 -0
  66. package/src/components/Input/Input.tsx +48 -0
  67. package/src/components/Input/index.ts +1 -0
  68. package/src/components/LineChart/LineChart.tsx +251 -0
  69. package/src/components/LineChart/index.ts +1 -0
  70. package/src/components/Markdown/Markdown.tsx +40 -0
  71. package/src/components/Markdown/index.ts +1 -0
  72. package/src/components/Message/Message.tsx +59 -0
  73. package/src/components/Message/components/MessageBody.tsx +9 -0
  74. package/src/components/Message/components/MessageDescription.tsx +9 -0
  75. package/src/components/Message/components/MessageIcon.tsx +13 -0
  76. package/src/components/Message/components/MessageTitle.tsx +9 -0
  77. package/src/components/Message/index.ts +10 -0
  78. package/src/components/MetricList/MetricList.tsx +13 -0
  79. package/src/components/MetricList/MetricRow.tsx +30 -0
  80. package/src/components/MetricList/index.ts +2 -0
  81. package/src/components/Modal/Modal.tsx +146 -0
  82. package/src/components/Modal/components/ModalBody.tsx +9 -0
  83. package/src/components/Modal/components/ModalContext.tsx +27 -0
  84. package/src/components/Modal/components/ModalFooter.tsx +9 -0
  85. package/src/components/Modal/components/ModalHeader.tsx +29 -0
  86. package/src/components/Modal/components/index.ts +9 -0
  87. package/src/components/Modal/index.ts +13 -0
  88. package/src/components/NavBottom/NavBottom.tsx +53 -0
  89. package/src/components/NavBottom/index.ts +3 -0
  90. package/src/components/NavSide/NavItem.tsx +39 -0
  91. package/src/components/NavSide/NavSide.tsx +40 -0
  92. package/src/components/NavSide/index.ts +2 -0
  93. package/src/components/NavSide/types.ts +36 -0
  94. package/src/components/Pagination/Pagination.tsx +86 -0
  95. package/src/components/Pagination/index.ts +2 -0
  96. package/src/components/Popover/Popover.tsx +68 -0
  97. package/src/components/Popover/components/PopoverBody.tsx +32 -0
  98. package/src/components/Popover/components/PopoverClose.tsx +26 -0
  99. package/src/components/Popover/components/PopoverContext.tsx +24 -0
  100. package/src/components/Popover/components/PopoverTrigger.tsx +31 -0
  101. package/src/components/Popover/index.ts +10 -0
  102. package/src/components/ProgressBar/ProgressBar.tsx +42 -0
  103. package/src/components/ProgressBar/index.ts +1 -0
  104. package/src/components/RadioButton/RadioButton.tsx +89 -0
  105. package/src/components/RadioButton/index.ts +1 -0
  106. package/src/components/RadioButtonGroup/RadioButtonGroup.tsx +193 -0
  107. package/src/components/RadioButtonGroup/index.ts +5 -0
  108. package/src/components/SearchInput/SearchInput.tsx +45 -0
  109. package/src/components/SearchInput/index.ts +2 -0
  110. package/src/components/Select/Select.tsx +289 -0
  111. package/src/components/Select/SelectDropdown.tsx +90 -0
  112. package/src/components/Select/SelectTrigger.tsx +130 -0
  113. package/src/components/Select/index.ts +3 -0
  114. package/src/components/Select/useSelectKeyboard.ts +111 -0
  115. package/src/components/Separator/Separator.tsx +20 -0
  116. package/src/components/Separator/index.ts +1 -0
  117. package/src/components/Sheet/Sheet.tsx +136 -0
  118. package/src/components/Sheet/components/SheetBody.tsx +9 -0
  119. package/src/components/Sheet/components/SheetContext.tsx +23 -0
  120. package/src/components/Sheet/components/SheetFooter.tsx +9 -0
  121. package/src/components/Sheet/components/SheetHeader.tsx +29 -0
  122. package/src/components/Sheet/components/index.ts +9 -0
  123. package/src/components/Sheet/index.ts +13 -0
  124. package/src/components/Skeleton/Skeleton.tsx +7 -0
  125. package/src/components/Skeleton/index.ts +1 -0
  126. package/src/components/Sparkline/Sparkline.tsx +93 -0
  127. package/src/components/Sparkline/index.ts +1 -0
  128. package/src/components/Spinner/Spinner.tsx +41 -0
  129. package/src/components/Spinner/index.ts +1 -0
  130. package/src/components/StatsCard/StatsCard.tsx +40 -0
  131. package/src/components/StatsCard/index.ts +1 -0
  132. package/src/components/Switch/Switch.tsx +128 -0
  133. package/src/components/Switch/index.ts +1 -0
  134. package/src/components/Tabs/Tabs.tsx +49 -0
  135. package/src/components/Tabs/components/TabsContext.tsx +35 -0
  136. package/src/components/Tabs/components/TabsList.tsx +98 -0
  137. package/src/components/Tabs/components/TabsPanels.tsx +26 -0
  138. package/src/components/Tabs/components/TabsTrigger.tsx +69 -0
  139. package/src/components/Tabs/index.ts +3 -0
  140. package/src/components/TagChip/TagChip.tsx +46 -0
  141. package/src/components/TagChip/index.ts +1 -0
  142. package/src/components/TagInput/TagInput.tsx +60 -0
  143. package/src/components/TagInput/index.ts +1 -0
  144. package/src/components/Text/Text.tsx +35 -0
  145. package/src/components/Text/index.ts +1 -0
  146. package/src/components/TextInline/TextInline.tsx +35 -0
  147. package/src/components/TextInline/index.ts +1 -0
  148. package/src/components/Textarea/Textarea.tsx +20 -0
  149. package/src/components/Textarea/index.ts +1 -0
  150. package/src/components/TimePicker/PeriodSelector.tsx +28 -0
  151. package/src/components/TimePicker/TimeColumn.tsx +62 -0
  152. package/src/components/TimePicker/TimePicker.tsx +323 -0
  153. package/src/components/TimePicker/index.ts +7 -0
  154. package/src/components/TimePicker/timepicker.hooks.ts +173 -0
  155. package/src/components/TimePicker/timepicker.types.ts +101 -0
  156. package/src/components/Toast/Toast.tsx +111 -0
  157. package/src/components/Toast/index.ts +1 -0
  158. package/src/components/Toggle/Toggle.tsx +72 -0
  159. package/src/components/Toggle/index.ts +1 -0
  160. package/src/components/ToggleGroup/ToggleGroup.tsx +14 -0
  161. package/src/components/ToggleGroup/ToggleGroupContainer.tsx +19 -0
  162. package/src/components/ToggleGroup/ToggleGroupItem.tsx +51 -0
  163. package/src/components/ToggleGroup/ToggleGroupMultiple.tsx +61 -0
  164. package/src/components/ToggleGroup/ToggleGroupSingle.tsx +105 -0
  165. package/src/components/ToggleGroup/index.ts +2 -0
  166. package/src/components/ToggleGroup/toggleGroup.types.ts +55 -0
  167. package/src/components/Tooltip/Tooltip.tsx +66 -0
  168. package/src/components/Tooltip/components/TooltipBody.tsx +30 -0
  169. package/src/components/Tooltip/components/TooltipContext.tsx +22 -0
  170. package/src/components/Tooltip/components/TooltipTrigger.tsx +27 -0
  171. package/src/components/Tooltip/index.ts +9 -0
  172. package/src/date-time/arithmetic.ts +101 -0
  173. package/src/date-time/boundaries.ts +91 -0
  174. package/src/date-time/compare.ts +85 -0
  175. package/src/date-time/duration.ts +63 -0
  176. package/src/date-time/elapsed.ts +18 -0
  177. package/src/date-time/format.ts +722 -0
  178. package/src/date-time/index.ts +279 -0
  179. package/src/date-time/now.ts +70 -0
  180. package/src/date-time/parse.ts +170 -0
  181. package/src/date-time/serialize.ts +90 -0
  182. package/src/date-time/timezone.ts +47 -0
  183. package/src/date-time/validate.ts +278 -0
  184. package/src/hooks/index.ts +10 -0
  185. package/src/hooks/useCollapsible.ts +16 -0
  186. package/src/hooks/useControllableState.ts +54 -0
  187. package/src/hooks/useDebouncedCallback.ts +21 -0
  188. package/src/hooks/useDebouncedState.ts +20 -0
  189. package/src/hooks/useDeviceFormFactor.ts +49 -0
  190. package/src/hooks/useLocalStorage.ts +67 -0
  191. package/src/hooks/useMergedFloatingRef.ts +29 -0
  192. package/src/hooks/usePresence.ts +127 -0
  193. package/src/hooks/useStack.ts +99 -0
  194. package/src/hooks/useTheme.ts +105 -0
  195. package/src/internal/Slot.tsx +79 -0
  196. package/src/internal/index.ts +2 -0
  197. package/src/internal/rovingFocus.ts +39 -0
  198. package/src/internal/types.ts +10 -0
  199. package/src/lib/EmptyBoundary.tsx +12 -0
  200. package/src/lib/ErrorBoundary.tsx +48 -0
  201. package/src/lib/contexts/ComponentsContext/ComponentsContext.tsx +34 -0
  202. package/src/lib/contexts/ComponentsContext/index.ts +1 -0
  203. package/src/lib/contexts/OverlayContext/OverlayContext.tsx +93 -0
  204. package/src/lib/contexts/OverlayContext/hooks/useModal.tsx +125 -0
  205. package/src/lib/contexts/OverlayContext/hooks/useToast.ts +80 -0
  206. package/src/lib/contexts/OverlayContext/index.ts +6 -0
  207. package/src/lib/format.ts +51 -0
  208. package/src/lib/utils.ts +10 -0
  209. package/src/lib/withEmpty.tsx +14 -0
  210. package/src/lib/withErrorBoundary.tsx +16 -0
  211. package/src/lib/withSuspense.tsx +16 -0
  212. package/src/lib/withSuspenseAndErrorBoundary.tsx +26 -0
  213. package/src/styles/base.css +41 -0
  214. package/src/theme/index.ts +37 -0
  215. package/src/theme/palette.json +100 -0
  216. package/src/theme/palette.schema.json +40 -0
  217. package/src/theme/schema.ts +122 -0
  218. package/src/theme/theme.json +349 -0
  219. package/src/theme/theme.schema.json +876 -0
  220. package/src/theme/typography.json +7 -0
  221. package/src/theme/typography.schema.json +36 -0
  222. package/src/typography/Body.tsx +8 -0
  223. package/src/typography/Caption.tsx +8 -0
  224. package/src/typography/Code.tsx +8 -0
  225. package/src/typography/Display.tsx +8 -0
  226. package/src/typography/Emphasis.tsx +8 -0
  227. package/src/typography/Heading.tsx +23 -0
  228. package/src/typography/Label.tsx +10 -0
  229. package/src/typography/Lead.tsx +8 -0
  230. package/src/typography/Mono.tsx +8 -0
  231. package/src/typography/Muted.tsx +8 -0
  232. package/src/typography/SectionTitle.tsx +8 -0
  233. package/src/typography/Subtitle.tsx +8 -0
  234. package/src/typography/Timestamp.tsx +8 -0
  235. package/src/typography/index.ts +10 -0
  236. package/tailwind.config.ts +261 -0
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Date/time arithmetic utilities
3
+ *
4
+ * Functions that modify or calculate differences between dates
5
+ */
6
+
7
+ import { Temporal } from "@js-temporal/polyfill";
8
+
9
+ /**
10
+ * Add days to a date
11
+ */
12
+ export function addDays(date: Temporal.PlainDate, days: number): Temporal.PlainDate {
13
+ return date.add({ days });
14
+ }
15
+
16
+ /**
17
+ * Subtract days from a date
18
+ */
19
+ export function subtractDays(date: Temporal.PlainDate, days: number): Temporal.PlainDate {
20
+ return date.subtract({ days });
21
+ }
22
+
23
+ /**
24
+ * Add months to a date
25
+ */
26
+ export function addMonths(date: Temporal.PlainDate, months: number): Temporal.PlainDate {
27
+ return date.add({ months });
28
+ }
29
+
30
+ /**
31
+ * Subtract months from a date
32
+ */
33
+ export function subtractMonths(date: Temporal.PlainDate, months: number): Temporal.PlainDate {
34
+ return date.subtract({ months });
35
+ }
36
+
37
+ /**
38
+ * Add weeks to a date
39
+ */
40
+ export function addWeeks(date: Temporal.PlainDate, weeks: number): Temporal.PlainDate {
41
+ return date.add({ weeks });
42
+ }
43
+
44
+ /**
45
+ * Subtract weeks from a date
46
+ */
47
+ export function subtractWeeks(date: Temporal.PlainDate, weeks: number): Temporal.PlainDate {
48
+ return date.subtract({ weeks });
49
+ }
50
+
51
+ /**
52
+ * Get the difference in days between two dates
53
+ */
54
+ export function diffInDays(from: Temporal.PlainDate, to: Temporal.PlainDate): number {
55
+ return from.until(to, { largestUnit: "day" }).days;
56
+ }
57
+
58
+ /**
59
+ * Get the difference in months between two dates
60
+ */
61
+ export function diffInMonths(from: Temporal.PlainDate, to: Temporal.PlainDate): number {
62
+ const diff = from.until(to, { largestUnit: "month" });
63
+ return diff.months + diff.years * 12;
64
+ }
65
+
66
+ /**
67
+ * Get the difference in minutes between two instants
68
+ */
69
+ export function differenceInMinutes(from: Temporal.Instant, to: Temporal.Instant): number {
70
+ const diff = from.until(to, { largestUnit: "minute" });
71
+ return Math.floor(diff.total("minutes"));
72
+ }
73
+
74
+ /**
75
+ * Generate an array of dates from start to end (inclusive)
76
+ *
77
+ * @example
78
+ * eachDayOfInterval(parseDate('2025-01-15'), parseDate('2025-01-17'))
79
+ * // → [2025-01-15, 2025-01-16, 2025-01-17]
80
+ */
81
+ export function eachDayOfInterval(start: Temporal.PlainDate, end: Temporal.PlainDate): Temporal.PlainDate[] {
82
+ const dates: Temporal.PlainDate[] = [];
83
+ let current = start;
84
+
85
+ // Handle both forward and backward intervals
86
+ if (Temporal.PlainDate.compare(start, end) <= 0) {
87
+ // Forward: start <= end
88
+ while (Temporal.PlainDate.compare(current, end) <= 0) {
89
+ dates.push(current);
90
+ current = current.add({ days: 1 });
91
+ }
92
+ } else {
93
+ // Backward: start > end
94
+ while (Temporal.PlainDate.compare(current, end) >= 0) {
95
+ dates.push(current);
96
+ current = current.subtract({ days: 1 });
97
+ }
98
+ }
99
+
100
+ return dates;
101
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Time period boundary utilities
3
+ *
4
+ * Functions that find the start/end of time periods (day, week, month, year)
5
+ */
6
+
7
+ import type { Temporal } from "@js-temporal/polyfill";
8
+
9
+ /**
10
+ * Get the start of the day (midnight)
11
+ */
12
+ export function startOfDay(date: Temporal.PlainDate): Temporal.PlainDateTime {
13
+ return date.toPlainDateTime({ hour: 0, minute: 0, second: 0 });
14
+ }
15
+
16
+ /**
17
+ * Get the end of the day (23:59:59.999999999)
18
+ */
19
+ export function endOfDay(date: Temporal.PlainDate): Temporal.PlainDateTime {
20
+ return date.toPlainDateTime({
21
+ hour: 23,
22
+ minute: 59,
23
+ second: 59,
24
+ millisecond: 999,
25
+ microsecond: 999,
26
+ nanosecond: 999,
27
+ });
28
+ }
29
+
30
+ /**
31
+ * First day of the week, as used by calendars: 0 = Sunday through 6 = Saturday.
32
+ * Note this is NOT Temporal's `dayOfWeek`, which is ISO 8601 (1 = Monday,
33
+ * 7 = Sunday) — `daysSinceWeekStart` converts between the two.
34
+ */
35
+ export type WeekStartsOn = 0 | 1 | 2 | 3 | 4 | 5 | 6;
36
+
37
+ /**
38
+ * How many days `date` sits past the start of its week, 0-6.
39
+ */
40
+ function daysSinceWeekStart(date: Temporal.PlainDate, weekStartsOn: WeekStartsOn): number {
41
+ // weekStartsOn counts from Sunday; dayOfWeek counts from Monday and uses 7
42
+ // for Sunday, so Sunday maps to 7 rather than 0.
43
+ const isoWeekStart = weekStartsOn === 0 ? 7 : weekStartsOn;
44
+ return (date.dayOfWeek - isoWeekStart + 7) % 7;
45
+ }
46
+
47
+ /**
48
+ * Get the start of the week (Monday by default, configurable)
49
+ * @param date The date to find the week start for
50
+ * @param weekStartsOn 0 = Sunday, 1 = Monday (default), through 6 = Saturday
51
+ */
52
+ export function startOfWeek(date: Temporal.PlainDate, weekStartsOn: WeekStartsOn = 1): Temporal.PlainDate {
53
+ return date.subtract({ days: daysSinceWeekStart(date, weekStartsOn) });
54
+ }
55
+
56
+ /**
57
+ * Get the end of the week — the day before the next week's start.
58
+ * @param date The date to find the week end for
59
+ * @param weekStartsOn 0 = Sunday, 1 = Monday (default), through 6 = Saturday
60
+ */
61
+ export function endOfWeek(date: Temporal.PlainDate, weekStartsOn: WeekStartsOn = 1): Temporal.PlainDate {
62
+ return date.add({ days: 6 - daysSinceWeekStart(date, weekStartsOn) });
63
+ }
64
+
65
+ /**
66
+ * Get the start of the month
67
+ */
68
+ export function startOfMonth(date: Temporal.PlainDate): Temporal.PlainDate {
69
+ return date.with({ day: 1 });
70
+ }
71
+
72
+ /**
73
+ * Get the end of the month
74
+ */
75
+ export function endOfMonth(date: Temporal.PlainDate): Temporal.PlainDate {
76
+ return date.with({ day: date.daysInMonth });
77
+ }
78
+
79
+ /**
80
+ * Get the start of the year
81
+ */
82
+ export function startOfYear(date: Temporal.PlainDate): Temporal.PlainDate {
83
+ return date.with({ month: 1, day: 1 });
84
+ }
85
+
86
+ /**
87
+ * Get the end of the year
88
+ */
89
+ export function endOfYear(date: Temporal.PlainDate): Temporal.PlainDate {
90
+ return date.with({ month: 12, day: 31 });
91
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Comparison utilities
3
+ *
4
+ * Boolean comparison operations for dates and instants
5
+ */
6
+
7
+ import { Temporal } from "@js-temporal/polyfill";
8
+ import { now, today } from "./now";
9
+
10
+ /**
11
+ * Check if date A is before date B
12
+ */
13
+ export function isBefore(a: Temporal.PlainDate, b: Temporal.PlainDate): boolean {
14
+ return Temporal.PlainDate.compare(a, b) < 0;
15
+ }
16
+
17
+ /**
18
+ * Check if date A is after date B
19
+ */
20
+ export function isAfter(a: Temporal.PlainDate, b: Temporal.PlainDate): boolean {
21
+ return Temporal.PlainDate.compare(a, b) > 0;
22
+ }
23
+
24
+ /**
25
+ * Check if two dates are the same day
26
+ */
27
+ export function isSameDay(a: Temporal.PlainDate, b: Temporal.PlainDate): boolean {
28
+ return Temporal.PlainDate.compare(a, b) === 0;
29
+ }
30
+
31
+ /**
32
+ * Check if two dates are in the same month and year
33
+ */
34
+ export function isSameMonth(a: Temporal.PlainDate, b: Temporal.PlainDate): boolean {
35
+ return a.year === b.year && a.month === b.month;
36
+ }
37
+
38
+ /**
39
+ * Check if instant A is before instant B
40
+ */
41
+ export function isInstantBefore(a: Temporal.Instant, b: Temporal.Instant): boolean {
42
+ return Temporal.Instant.compare(a, b) < 0;
43
+ }
44
+
45
+ /**
46
+ * Check if instant A is after instant B
47
+ */
48
+ export function isInstantAfter(a: Temporal.Instant, b: Temporal.Instant): boolean {
49
+ return Temporal.Instant.compare(a, b) > 0;
50
+ }
51
+
52
+ /**
53
+ * Check if a date is today
54
+ */
55
+ export function isToday(date: Temporal.PlainDate): boolean {
56
+ return isSameDay(date, today());
57
+ }
58
+
59
+ /**
60
+ * Check if a date is in the past
61
+ */
62
+ export function isPast(date: Temporal.PlainDate): boolean {
63
+ return isBefore(date, today());
64
+ }
65
+
66
+ /**
67
+ * Check if a date is in the future
68
+ */
69
+ export function isFuture(date: Temporal.PlainDate): boolean {
70
+ return isAfter(date, today());
71
+ }
72
+
73
+ /**
74
+ * Check if an instant is in the past
75
+ */
76
+ export function isInstantPast(instant: Temporal.Instant): boolean {
77
+ return isInstantBefore(instant, now());
78
+ }
79
+
80
+ /**
81
+ * Check if an instant is in the future
82
+ */
83
+ export function isInstantFuture(instant: Temporal.Instant): boolean {
84
+ return isInstantAfter(instant, now());
85
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Duration utilities
3
+ *
4
+ * Functions for creating and converting Duration objects
5
+ */
6
+
7
+ import { Temporal } from "@js-temporal/polyfill";
8
+
9
+ /**
10
+ * Create a duration from hours
11
+ */
12
+ export function hours(n: number): Temporal.Duration {
13
+ return Temporal.Duration.from({ hours: n });
14
+ }
15
+
16
+ /**
17
+ * Create a duration from minutes
18
+ */
19
+ export function minutes(n: number): Temporal.Duration {
20
+ return Temporal.Duration.from({ minutes: n });
21
+ }
22
+
23
+ /**
24
+ * Create a duration from days
25
+ */
26
+ export function days(n: number): Temporal.Duration {
27
+ return Temporal.Duration.from({ days: n });
28
+ }
29
+
30
+ /**
31
+ * Create a duration from weeks
32
+ */
33
+ export function weeks(n: number): Temporal.Duration {
34
+ return Temporal.Duration.from({ weeks: n });
35
+ }
36
+
37
+ /**
38
+ * Get the total milliseconds of a duration
39
+ */
40
+ export function toMilliseconds(duration: Temporal.Duration): number {
41
+ return duration.total({ unit: "milliseconds" });
42
+ }
43
+
44
+ /**
45
+ * Get the total seconds of a duration
46
+ */
47
+ export function toSeconds(duration: Temporal.Duration): number {
48
+ return duration.total({ unit: "seconds" });
49
+ }
50
+
51
+ /**
52
+ * Get the total minutes of a duration
53
+ */
54
+ export function toMinutes(duration: Temporal.Duration): number {
55
+ return duration.total({ unit: "minutes" });
56
+ }
57
+
58
+ /**
59
+ * Get the total hours of a duration
60
+ */
61
+ export function toHours(duration: Temporal.Duration): number {
62
+ return duration.total({ unit: "hours" });
63
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Elapsed-time helpers
3
+ *
4
+ * Replaces the legacy `Date.now() - start` pattern with Temporal-native
5
+ * equivalents. Native `Date` is banned codebase-wide — see ADR 0003 and
6
+ * `docs/engineering/reference/conventions/logging-conventions.md`.
7
+ */
8
+
9
+ import { Temporal } from "@js-temporal/polyfill";
10
+
11
+ export function elapsedMs(start: Temporal.Instant): number {
12
+ const ms = Temporal.Now.instant().since(start).total({ unit: "milliseconds" });
13
+ return Math.max(0, Math.round(ms));
14
+ }
15
+
16
+ export function epochMs(instant: Temporal.Instant): number {
17
+ return Number(instant.epochMilliseconds);
18
+ }