bits-ui 1.8.0 → 2.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 (287) hide show
  1. package/dist/bits/accordion/accordion.svelte.d.ts +56 -53
  2. package/dist/bits/accordion/accordion.svelte.js +78 -89
  3. package/dist/bits/accordion/components/accordion-content.svelte +5 -3
  4. package/dist/bits/accordion/components/accordion-header.svelte +4 -2
  5. package/dist/bits/accordion/components/accordion-item.svelte +6 -3
  6. package/dist/bits/accordion/components/accordion-trigger.svelte +4 -2
  7. package/dist/bits/accordion/components/accordion.svelte +4 -2
  8. package/dist/bits/alert-dialog/components/alert-dialog-action.svelte +4 -2
  9. package/dist/bits/alert-dialog/components/alert-dialog-cancel.svelte +4 -2
  10. package/dist/bits/alert-dialog/components/alert-dialog-content.svelte +8 -3
  11. package/dist/bits/aspect-ratio/aspect-ratio.svelte.js +2 -2
  12. package/dist/bits/aspect-ratio/components/aspect-ratio.svelte +4 -2
  13. package/dist/bits/avatar/avatar.svelte.js +4 -4
  14. package/dist/bits/avatar/components/avatar-fallback.svelte +4 -2
  15. package/dist/bits/avatar/components/avatar-image.svelte +4 -2
  16. package/dist/bits/avatar/components/avatar.svelte +4 -2
  17. package/dist/bits/button/components/button.svelte +1 -1
  18. package/dist/bits/calendar/calendar.svelte.d.ts +1 -9
  19. package/dist/bits/calendar/calendar.svelte.js +47 -38
  20. package/dist/bits/calendar/components/calendar-cell.svelte +4 -2
  21. package/dist/bits/calendar/components/calendar-day.svelte +4 -2
  22. package/dist/bits/calendar/components/calendar-grid-body.svelte +4 -2
  23. package/dist/bits/calendar/components/calendar-grid-head.svelte +4 -2
  24. package/dist/bits/calendar/components/calendar-grid-row.svelte +4 -2
  25. package/dist/bits/calendar/components/calendar-grid.svelte +4 -2
  26. package/dist/bits/calendar/components/calendar-head-cell.svelte +4 -2
  27. package/dist/bits/calendar/components/calendar-header.svelte +4 -2
  28. package/dist/bits/calendar/components/calendar-heading.svelte +4 -2
  29. package/dist/bits/calendar/components/calendar-next-button.svelte +4 -2
  30. package/dist/bits/calendar/components/calendar-prev-button.svelte +4 -2
  31. package/dist/bits/checkbox/checkbox.svelte.js +4 -14
  32. package/dist/bits/checkbox/components/checkbox-group-label.svelte +4 -2
  33. package/dist/bits/checkbox/components/checkbox-group.svelte +4 -2
  34. package/dist/bits/checkbox/components/checkbox.svelte +4 -2
  35. package/dist/bits/collapsible/collapsible.svelte.js +4 -10
  36. package/dist/bits/collapsible/components/collapsible-content.svelte +5 -3
  37. package/dist/bits/collapsible/components/collapsible-trigger.svelte +4 -2
  38. package/dist/bits/collapsible/components/collapsible.svelte +4 -2
  39. package/dist/bits/combobox/components/combobox-input.svelte +1 -1
  40. package/dist/bits/combobox/components/combobox.svelte +1 -1
  41. package/dist/bits/command/command.svelte.js +13 -45
  42. package/dist/bits/command/components/_command-label.svelte +6 -7
  43. package/dist/bits/command/components/_command-label.svelte.d.ts +1 -1
  44. package/dist/bits/command/components/command-empty.svelte +4 -2
  45. package/dist/bits/command/components/command-group-heading.svelte +4 -2
  46. package/dist/bits/command/components/command-group-items.svelte +4 -2
  47. package/dist/bits/command/components/command-group.svelte +4 -2
  48. package/dist/bits/command/components/command-input.svelte +4 -2
  49. package/dist/bits/command/components/command-item.svelte +4 -2
  50. package/dist/bits/command/components/command-link-item.svelte +4 -2
  51. package/dist/bits/command/components/command-list.svelte +4 -2
  52. package/dist/bits/command/components/command-loading.svelte +4 -2
  53. package/dist/bits/command/components/command-separator.svelte +4 -2
  54. package/dist/bits/command/components/command-viewport.svelte +4 -2
  55. package/dist/bits/command/components/command.svelte +4 -2
  56. package/dist/bits/context-menu/components/context-menu-content-static.svelte +2 -3
  57. package/dist/bits/context-menu/components/context-menu-content.svelte +2 -3
  58. package/dist/bits/context-menu/components/context-menu-trigger.svelte +1 -1
  59. package/dist/bits/date-field/components/date-field-input.svelte +4 -2
  60. package/dist/bits/date-field/components/date-field-label.svelte +4 -2
  61. package/dist/bits/date-field/components/date-field-segment.svelte +4 -2
  62. package/dist/bits/date-field/date-field.svelte.d.ts +4 -4
  63. package/dist/bits/date-field/date-field.svelte.js +15 -33
  64. package/dist/bits/date-picker/components/date-picker-calendar.svelte +4 -2
  65. package/dist/bits/date-range-field/components/date-range-field-input.svelte +4 -2
  66. package/dist/bits/date-range-field/components/date-range-field-label.svelte +4 -2
  67. package/dist/bits/date-range-field/components/date-range-field.svelte +4 -2
  68. package/dist/bits/date-range-field/date-range-field.svelte.js +3 -13
  69. package/dist/bits/date-range-picker/components/date-range-picker-calendar.svelte +4 -2
  70. package/dist/bits/dialog/components/dialog-close.svelte +4 -2
  71. package/dist/bits/dialog/components/dialog-content.svelte +8 -2
  72. package/dist/bits/dialog/components/dialog-description.svelte +4 -2
  73. package/dist/bits/dialog/components/dialog-overlay.svelte +8 -3
  74. package/dist/bits/dialog/components/dialog-title.svelte +4 -2
  75. package/dist/bits/dialog/components/dialog-trigger.svelte +4 -2
  76. package/dist/bits/dialog/dialog.svelte.d.ts +1 -1
  77. package/dist/bits/dialog/dialog.svelte.js +19 -47
  78. package/dist/bits/dropdown-menu/components/dropdown-menu-content-static.svelte +6 -5
  79. package/dist/bits/dropdown-menu/components/dropdown-menu-content.svelte +6 -5
  80. package/dist/bits/index.d.ts +2 -0
  81. package/dist/bits/index.js +2 -0
  82. package/dist/bits/label/components/label.svelte +4 -2
  83. package/dist/bits/label/label.svelte.js +2 -2
  84. package/dist/bits/link-preview/components/link-preview-content-static.svelte +6 -2
  85. package/dist/bits/link-preview/components/link-preview-content.svelte +6 -2
  86. package/dist/bits/link-preview/components/link-preview-trigger.svelte +5 -3
  87. package/dist/bits/link-preview/link-preview.svelte.js +3 -14
  88. package/dist/bits/menu/components/menu-checkbox-group.svelte +4 -2
  89. package/dist/bits/menu/components/menu-checkbox-item.svelte +6 -4
  90. package/dist/bits/menu/components/menu-content-static.svelte +6 -5
  91. package/dist/bits/menu/components/menu-content.svelte +6 -5
  92. package/dist/bits/menu/components/menu-group-heading.svelte +4 -2
  93. package/dist/bits/menu/components/menu-group.svelte +4 -2
  94. package/dist/bits/menu/components/menu-item.svelte +4 -2
  95. package/dist/bits/menu/components/menu-radio-group.svelte +4 -2
  96. package/dist/bits/menu/components/menu-radio-item.svelte +4 -2
  97. package/dist/bits/menu/components/menu-separator.svelte +4 -2
  98. package/dist/bits/menu/components/menu-sub-content-static.svelte +6 -5
  99. package/dist/bits/menu/components/menu-sub-content.svelte +6 -5
  100. package/dist/bits/menu/components/menu-sub-trigger.svelte +6 -3
  101. package/dist/bits/menu/components/menu-trigger.svelte +5 -3
  102. package/dist/bits/menu/menu.svelte.d.ts +7 -20
  103. package/dist/bits/menu/menu.svelte.js +26 -54
  104. package/dist/bits/menubar/components/menubar-content-static.svelte +4 -2
  105. package/dist/bits/menubar/components/menubar-content.svelte +4 -2
  106. package/dist/bits/menubar/components/menubar-menu.svelte +4 -2
  107. package/dist/bits/menubar/components/menubar-trigger.svelte +14 -6
  108. package/dist/bits/menubar/components/menubar.svelte +4 -2
  109. package/dist/bits/menubar/menubar.svelte.d.ts +24 -20
  110. package/dist/bits/menubar/menubar.svelte.js +40 -56
  111. package/dist/bits/meter/components/meter.svelte +4 -2
  112. package/dist/bits/meter/meter.svelte.js +2 -2
  113. package/dist/bits/navigation-menu/components/navigation-menu-content-impl.svelte +5 -2
  114. package/dist/bits/navigation-menu/components/navigation-menu-content.svelte +8 -3
  115. package/dist/bits/navigation-menu/components/navigation-menu-indicator-impl.svelte +4 -2
  116. package/dist/bits/navigation-menu/components/navigation-menu-indicator.svelte +6 -4
  117. package/dist/bits/navigation-menu/components/navigation-menu-item.svelte +6 -3
  118. package/dist/bits/navigation-menu/components/navigation-menu-link.svelte +4 -2
  119. package/dist/bits/navigation-menu/components/navigation-menu-list.svelte +4 -2
  120. package/dist/bits/navigation-menu/components/navigation-menu-sub.svelte +4 -2
  121. package/dist/bits/navigation-menu/components/navigation-menu-trigger.svelte +4 -2
  122. package/dist/bits/navigation-menu/components/navigation-menu-viewport.svelte +5 -3
  123. package/dist/bits/navigation-menu/components/navigation-menu.svelte +4 -2
  124. package/dist/bits/navigation-menu/navigation-menu.svelte.js +13 -50
  125. package/dist/bits/pagination/components/pagination-next-button.svelte +4 -2
  126. package/dist/bits/pagination/components/pagination-page.svelte +4 -2
  127. package/dist/bits/pagination/components/pagination-prev-button.svelte +4 -2
  128. package/dist/bits/pagination/components/pagination.svelte +4 -2
  129. package/dist/bits/pagination/pagination.svelte.js +4 -4
  130. package/dist/bits/pin-input/components/pin-input-cell.svelte +4 -2
  131. package/dist/bits/pin-input/components/pin-input.svelte +5 -3
  132. package/dist/bits/pin-input/pin-input.svelte.js +4 -10
  133. package/dist/bits/popover/components/popover-close.svelte +4 -2
  134. package/dist/bits/popover/components/popover-content-static.svelte +6 -2
  135. package/dist/bits/popover/components/popover-content.svelte +6 -2
  136. package/dist/bits/popover/components/popover-trigger.svelte +5 -3
  137. package/dist/bits/popover/popover.svelte.js +4 -18
  138. package/dist/bits/progress/components/progress.svelte +4 -2
  139. package/dist/bits/progress/progress.svelte.js +2 -2
  140. package/dist/bits/radio-group/components/radio-group-item.svelte +4 -2
  141. package/dist/bits/radio-group/components/radio-group.svelte +4 -2
  142. package/dist/bits/radio-group/radio-group.svelte.js +4 -7
  143. package/dist/bits/range-calendar/components/range-calendar-cell.svelte +4 -2
  144. package/dist/bits/range-calendar/components/range-calendar-day.svelte +4 -2
  145. package/dist/bits/range-calendar/components/range-calendar.svelte +4 -2
  146. package/dist/bits/range-calendar/range-calendar.svelte.js +4 -4
  147. package/dist/bits/scroll-area/components/scroll-area-corner.svelte +8 -2
  148. package/dist/bits/scroll-area/components/scroll-area-scrollbar-auto.svelte +4 -1
  149. package/dist/bits/scroll-area/components/scroll-area-scrollbar-hover.svelte +1 -1
  150. package/dist/bits/scroll-area/components/scroll-area-scrollbar-scroll.svelte +5 -1
  151. package/dist/bits/scroll-area/components/scroll-area-scrollbar.svelte +4 -2
  152. package/dist/bits/scroll-area/components/scroll-area-thumb.svelte +8 -3
  153. package/dist/bits/scroll-area/components/scroll-area-viewport.svelte +4 -2
  154. package/dist/bits/scroll-area/components/scroll-area.svelte +4 -2
  155. package/dist/bits/scroll-area/scroll-area.svelte.js +13 -47
  156. package/dist/bits/select/components/select-content-static.svelte +6 -2
  157. package/dist/bits/select/components/select-content.svelte +6 -2
  158. package/dist/bits/select/components/select-group-heading.svelte +3 -2
  159. package/dist/bits/select/components/select-group.svelte +4 -2
  160. package/dist/bits/select/components/select-item.svelte +4 -2
  161. package/dist/bits/select/components/select-scroll-down-button.svelte +4 -2
  162. package/dist/bits/select/components/select-scroll-up-button.svelte +4 -2
  163. package/dist/bits/select/components/select-trigger.svelte +5 -3
  164. package/dist/bits/select/components/select-viewport.svelte +4 -2
  165. package/dist/bits/select/components/select.svelte +1 -1
  166. package/dist/bits/select/select.svelte.d.ts +0 -18
  167. package/dist/bits/select/select.svelte.js +10 -43
  168. package/dist/bits/separator/components/separator.svelte +4 -2
  169. package/dist/bits/separator/separator.svelte.js +2 -2
  170. package/dist/bits/slider/components/slider-range.svelte +4 -2
  171. package/dist/bits/slider/components/slider-thumb-label.svelte +50 -0
  172. package/dist/bits/slider/components/slider-thumb-label.svelte.d.ts +4 -0
  173. package/dist/bits/slider/components/slider-thumb.svelte +4 -2
  174. package/dist/bits/slider/components/slider-tick-label.svelte +50 -0
  175. package/dist/bits/slider/components/slider-tick-label.svelte.d.ts +4 -0
  176. package/dist/bits/slider/components/slider-tick.svelte +4 -2
  177. package/dist/bits/slider/components/slider.svelte +24 -5
  178. package/dist/bits/slider/exports.d.ts +3 -1
  179. package/dist/bits/slider/exports.js +2 -0
  180. package/dist/bits/slider/helpers.d.ts +14 -0
  181. package/dist/bits/slider/helpers.js +122 -0
  182. package/dist/bits/slider/slider.svelte.d.ts +91 -5
  183. package/dist/bits/slider/slider.svelte.js +194 -101
  184. package/dist/bits/slider/types.d.ts +105 -11
  185. package/dist/bits/switch/components/switch-thumb.svelte +4 -2
  186. package/dist/bits/switch/components/switch.svelte +4 -2
  187. package/dist/bits/switch/switch.svelte.js +3 -3
  188. package/dist/bits/tabs/components/tabs-content.svelte +4 -2
  189. package/dist/bits/tabs/components/tabs-list.svelte +4 -2
  190. package/dist/bits/tabs/components/tabs-trigger.svelte +4 -2
  191. package/dist/bits/tabs/components/tabs.svelte +4 -2
  192. package/dist/bits/tabs/tabs.svelte.js +6 -6
  193. package/dist/bits/time-field/components/time-field-hidden-input.svelte +10 -0
  194. package/dist/bits/{date-field/components/date-field-error.svelte.d.ts → time-field/components/time-field-hidden-input.svelte.d.ts} +6 -14
  195. package/dist/bits/time-field/components/time-field-input.svelte +39 -0
  196. package/dist/bits/time-field/components/time-field-input.svelte.d.ts +4 -0
  197. package/dist/bits/time-field/components/time-field-label.svelte +34 -0
  198. package/dist/bits/time-field/components/time-field-label.svelte.d.ts +4 -0
  199. package/dist/bits/time-field/components/time-field-segment.svelte +37 -0
  200. package/dist/bits/time-field/components/time-field-segment.svelte.d.ts +4 -0
  201. package/dist/bits/time-field/components/time-field.svelte +94 -0
  202. package/dist/bits/time-field/components/time-field.svelte.d.ts +20 -0
  203. package/dist/bits/time-field/exports.d.ts +5 -0
  204. package/dist/bits/time-field/exports.js +4 -0
  205. package/dist/bits/time-field/index.d.ts +1 -0
  206. package/dist/bits/time-field/index.js +1 -0
  207. package/dist/bits/time-field/time-field.svelte.d.ts +415 -0
  208. package/dist/bits/time-field/time-field.svelte.js +971 -0
  209. package/dist/bits/time-field/types.d.ts +137 -0
  210. package/dist/bits/time-field/types.js +1 -0
  211. package/dist/bits/time-range-field/components/time-range-field-input.svelte +43 -0
  212. package/dist/bits/time-range-field/components/time-range-field-input.svelte.d.ts +4 -0
  213. package/dist/bits/time-range-field/components/time-range-field-label.svelte +34 -0
  214. package/dist/bits/time-range-field/components/time-range-field-label.svelte.d.ts +4 -0
  215. package/dist/bits/time-range-field/components/time-range-field.svelte +144 -0
  216. package/dist/bits/time-range-field/components/time-range-field.svelte.d.ts +20 -0
  217. package/dist/bits/time-range-field/exports.d.ts +5 -0
  218. package/dist/bits/time-range-field/exports.js +4 -0
  219. package/dist/bits/time-range-field/index.d.ts +1 -0
  220. package/dist/bits/time-range-field/index.js +1 -0
  221. package/dist/bits/time-range-field/time-range-field.svelte.d.ts +90 -0
  222. package/dist/bits/time-range-field/time-range-field.svelte.js +210 -0
  223. package/dist/bits/time-range-field/types.d.ts +150 -0
  224. package/dist/bits/time-range-field/types.js +1 -0
  225. package/dist/bits/toggle/components/toggle.svelte +4 -2
  226. package/dist/bits/toggle/toggle.svelte.js +2 -2
  227. package/dist/bits/toggle-group/components/toggle-group-item.svelte +4 -2
  228. package/dist/bits/toggle-group/components/toggle-group.svelte +4 -2
  229. package/dist/bits/toggle-group/toggle-group.svelte.js +4 -4
  230. package/dist/bits/toolbar/components/toolbar-button.svelte +4 -2
  231. package/dist/bits/toolbar/components/toolbar-group-item.svelte +4 -2
  232. package/dist/bits/toolbar/components/toolbar-group.svelte +4 -2
  233. package/dist/bits/toolbar/components/toolbar-link.svelte +4 -2
  234. package/dist/bits/toolbar/components/toolbar.svelte +4 -2
  235. package/dist/bits/toolbar/toolbar.svelte.js +7 -7
  236. package/dist/bits/tooltip/components/tooltip-content-static.svelte +6 -2
  237. package/dist/bits/tooltip/components/tooltip-content.svelte +6 -2
  238. package/dist/bits/tooltip/components/tooltip-trigger.svelte +5 -3
  239. package/dist/bits/tooltip/tooltip.svelte.js +3 -14
  240. package/dist/bits/utilities/dismissible-layer/dismissible-layer.svelte +2 -0
  241. package/dist/bits/utilities/dismissible-layer/types.d.ts +2 -0
  242. package/dist/bits/utilities/dismissible-layer/use-dismissable-layer.svelte.d.ts +3 -3
  243. package/dist/bits/utilities/dismissible-layer/use-dismissable-layer.svelte.js +16 -25
  244. package/dist/bits/utilities/floating-layer/components/floating-layer-anchor.svelte +2 -1
  245. package/dist/bits/utilities/floating-layer/types.d.ts +1 -0
  246. package/dist/bits/utilities/floating-layer/use-floating-layer.svelte.d.ts +3 -2
  247. package/dist/bits/utilities/floating-layer/use-floating-layer.svelte.js +5 -26
  248. package/dist/bits/utilities/focus-scope/focus-scope.svelte +2 -0
  249. package/dist/bits/utilities/focus-scope/types.d.ts +2 -0
  250. package/dist/bits/utilities/focus-scope/use-focus-scope.svelte.d.ts +2 -1
  251. package/dist/bits/utilities/focus-scope/use-focus-scope.svelte.js +2 -8
  252. package/dist/bits/utilities/popper-layer/popper-layer-inner.svelte +4 -0
  253. package/dist/bits/utilities/popper-layer/popper-layer.svelte +3 -1
  254. package/dist/bits/utilities/presence-layer/presence-layer.svelte +2 -2
  255. package/dist/bits/utilities/presence-layer/types.d.ts +2 -1
  256. package/dist/bits/utilities/presence-layer/use-presence.svelte.d.ts +1 -1
  257. package/dist/bits/utilities/presence-layer/use-presence.svelte.js +19 -36
  258. package/dist/bits/utilities/text-selection-layer/text-selection-layer.svelte +2 -0
  259. package/dist/bits/utilities/text-selection-layer/types.d.ts +2 -0
  260. package/dist/bits/utilities/text-selection-layer/use-text-selection-layer.svelte.d.ts +3 -1
  261. package/dist/bits/utilities/text-selection-layer/use-text-selection-layer.svelte.js +2 -8
  262. package/dist/index.d.ts +1 -1
  263. package/dist/index.js +1 -1
  264. package/dist/internal/create-id.d.ts +8 -0
  265. package/dist/internal/create-id.js +5 -0
  266. package/dist/internal/date-time/field/helpers.d.ts +1 -0
  267. package/dist/internal/date-time/field/helpers.js +8 -2
  268. package/dist/internal/date-time/field/parts.d.ts +3 -1
  269. package/dist/internal/date-time/field/parts.js +10 -2
  270. package/dist/internal/date-time/field/segments.d.ts +9 -0
  271. package/dist/internal/date-time/field/segments.js +65 -0
  272. package/dist/internal/date-time/field/time-helpers.d.ts +77 -0
  273. package/dist/internal/date-time/field/time-helpers.js +301 -0
  274. package/dist/internal/date-time/field/types.d.ts +2 -2
  275. package/dist/internal/date-time/formatter.d.ts +11 -1
  276. package/dist/internal/date-time/formatter.js +56 -0
  277. package/dist/internal/date-time/utils.d.ts +7 -2
  278. package/dist/internal/date-time/utils.js +15 -1
  279. package/dist/internal/dom-context.svelte.d.ts +9 -0
  280. package/dist/internal/dom-context.svelte.js +26 -0
  281. package/dist/internal/use-roving-focus.svelte.d.ts +3 -3
  282. package/dist/internal/use-roving-focus.svelte.js +10 -11
  283. package/dist/shared/date/types.d.ts +27 -4
  284. package/dist/shared/index.d.ts +2 -2
  285. package/dist/types.d.ts +2 -0
  286. package/package.json +18 -16
  287. package/dist/bits/date-field/components/date-field-error.svelte +0 -0
@@ -0,0 +1,301 @@
1
+ import { isBrowser, isNull } from "../../is.js";
2
+ import { CalendarDateTime, Time, ZonedDateTime } from "@internationalized/date";
3
+ import { ALL_TIME_SEGMENT_PARTS, EDITABLE_TIME_SEGMENT_PARTS } from "./parts.js";
4
+ import { getTimeSegments } from "./segments.js";
5
+ import { styleToString } from "svelte-toolbelt";
6
+ import { useId } from "../../use-id.js";
7
+ import { getPlaceholder } from "../placeholders.js";
8
+ import { isZonedDateTime } from "../utils.js";
9
+ export function initializeSegmentValues() {
10
+ const initialParts = EDITABLE_TIME_SEGMENT_PARTS.map((part) => {
11
+ if (part === "dayPeriod") {
12
+ return [part, "AM"];
13
+ }
14
+ return [part, null];
15
+ }).filter(([key]) => {
16
+ if (key === "literal" || key === null)
17
+ return false;
18
+ return true;
19
+ });
20
+ return Object.fromEntries(initialParts);
21
+ }
22
+ function createTimeContentObj(props) {
23
+ const { segmentValues, formatter, locale, timeRef } = props;
24
+ const content = Object.keys(segmentValues).reduce((obj, part) => {
25
+ if (!isEditableTimeSegmentPart(part))
26
+ return obj;
27
+ if (part === "dayPeriod") {
28
+ const value = segmentValues[part];
29
+ if (!isNull(value)) {
30
+ obj[part] = value;
31
+ }
32
+ else {
33
+ obj[part] = getPlaceholder(part, "AM", locale);
34
+ }
35
+ }
36
+ else {
37
+ obj[part] = getPartContent(part);
38
+ }
39
+ return obj;
40
+ }, {});
41
+ function getPartContent(part) {
42
+ const value = segmentValues[part];
43
+ const leadingZero = typeof value === "string" && value?.startsWith("0");
44
+ const intValue = value !== null ? Number.parseInt(value) : null;
45
+ if (!isNull(value) && !isNull(intValue)) {
46
+ const formatted = formatter.part(timeRef.set({ [part]: value }), part, {
47
+ hourCycle: props.hourCycle === 24 ? "h23" : undefined,
48
+ });
49
+ /**
50
+ * If we're operating in a 12 hour clock and the part is an hour, we handle
51
+ * the conversion to 12 hour format with 2 digit hours and leading zeros here.
52
+ */
53
+ if (part === "hour" && "dayPeriod" in segmentValues && props.hourCycle !== 24) {
54
+ /**
55
+ * If the value is over 12, we convert to 12 hour format and add leading
56
+ * zeroes if the value is less than 10.
57
+ */
58
+ if (intValue > 12) {
59
+ const hour = intValue - 12;
60
+ if (hour === 0) {
61
+ return "12";
62
+ }
63
+ else if (hour < 10) {
64
+ return `0${hour}`;
65
+ }
66
+ else {
67
+ return `${hour}`;
68
+ }
69
+ }
70
+ /**
71
+ * If the value is 0, we convert to 12, since 0 is not a valid 12 hour time.
72
+ */
73
+ if (intValue === 0) {
74
+ return "12";
75
+ }
76
+ /**
77
+ * If the value is less than 10, we add a leading zero to the value.
78
+ */
79
+ if (intValue < 10) {
80
+ return `0${intValue}`;
81
+ }
82
+ /**
83
+ * Otherwise, we don't need to do anything to the value.
84
+ */
85
+ return `${intValue}`;
86
+ }
87
+ if (leadingZero && formatted.length === 1) {
88
+ return `0${formatted}`;
89
+ }
90
+ return formatted;
91
+ }
92
+ else {
93
+ return getPlaceholder(part, "", locale);
94
+ }
95
+ }
96
+ return content;
97
+ }
98
+ function createTimeContentArr(props) {
99
+ const { granularity, timeRef, formatter, contentObj, hideTimeZone, hourCycle } = props;
100
+ const parts = formatter.toParts(timeRef, getOptsByGranularity(granularity, hourCycle));
101
+ const timeSegmentContentArr = parts
102
+ .map((part) => {
103
+ const defaultParts = ["literal", "timeZoneName", null];
104
+ if (defaultParts.includes(part.type) || !isEditableTimeSegmentPart(part.type)) {
105
+ return {
106
+ part: part.type,
107
+ value: part.value,
108
+ };
109
+ }
110
+ return {
111
+ part: part.type,
112
+ value: contentObj[part.type],
113
+ };
114
+ })
115
+ .filter((segment) => {
116
+ if (isNull(segment.part) || isNull(segment.value))
117
+ return false;
118
+ if (segment.part === "timeZoneName" && (!isZonedDateTime(timeRef) || hideTimeZone)) {
119
+ return false;
120
+ }
121
+ return true;
122
+ });
123
+ return timeSegmentContentArr;
124
+ }
125
+ export function createTimeContent(props) {
126
+ const contentObj = createTimeContentObj(props);
127
+ const contentArr = createTimeContentArr({
128
+ contentObj,
129
+ ...props,
130
+ });
131
+ return {
132
+ obj: contentObj,
133
+ arr: contentArr,
134
+ };
135
+ }
136
+ function getOptsByGranularity(granularity, hourCycle) {
137
+ const opts = {
138
+ hour: "2-digit",
139
+ minute: "2-digit",
140
+ second: "2-digit",
141
+ timeZoneName: "short",
142
+ hourCycle: hourCycle === 24 ? "h23" : undefined,
143
+ hour12: hourCycle === 24 ? false : undefined,
144
+ };
145
+ if (granularity === "hour") {
146
+ delete opts.minute;
147
+ delete opts.second;
148
+ }
149
+ if (granularity === "minute") {
150
+ delete opts.second;
151
+ }
152
+ return opts;
153
+ }
154
+ export function initTimeSegmentStates() {
155
+ return EDITABLE_TIME_SEGMENT_PARTS.reduce((acc, key) => {
156
+ acc[key] = {
157
+ lastKeyZero: false,
158
+ hasLeftFocus: true,
159
+ updating: null,
160
+ };
161
+ return acc;
162
+ }, {});
163
+ }
164
+ export function initTimeSegmentIds() {
165
+ return Object.fromEntries(ALL_TIME_SEGMENT_PARTS.map((part) => {
166
+ return [part, useId()];
167
+ }).filter(([key]) => key !== "literal"));
168
+ }
169
+ export function isEditableTimeSegmentPart(part) {
170
+ return EDITABLE_TIME_SEGMENT_PARTS.includes(part);
171
+ }
172
+ export function isAnyTimeSegmentPart(part) {
173
+ return ALL_TIME_SEGMENT_PARTS.includes(part);
174
+ }
175
+ /**
176
+ * Get the segments being used/ are rendered in the DOM.
177
+ * We're using this to determine when to set the value of
178
+ * the date picker, which is when all the segments have
179
+ * been filled.
180
+ */
181
+ function getUsedTimeSegments(fieldNode) {
182
+ if (!isBrowser || !fieldNode)
183
+ return [];
184
+ const usedSegments = getTimeSegments(fieldNode)
185
+ .map((el) => el.dataset.segment)
186
+ .filter((part) => {
187
+ return EDITABLE_TIME_SEGMENT_PARTS.includes(part);
188
+ });
189
+ return usedSegments;
190
+ }
191
+ export function getTimeValueFromSegments(props) {
192
+ const usedSegments = getUsedTimeSegments(props.fieldNode);
193
+ for (const part of usedSegments) {
194
+ const value = props.segmentObj[part];
195
+ if (isNull(value))
196
+ continue;
197
+ // @ts-expect-error shhh
198
+ props.timeRef = props.timeRef.set({ [part]: props.segmentObj[part] });
199
+ }
200
+ return props.timeRef;
201
+ }
202
+ /**
203
+ * Check if all the segments being used have been filled.
204
+ * We use this to determine when we should set the value
205
+ * store of the date field(s).
206
+ *
207
+ * @param segmentValues - The current `SegmentValueObj`
208
+ * @param fieldNode - The id of the date field
209
+ */
210
+ export function areAllTimeSegmentsFilled(segmentValues, fieldNode) {
211
+ const usedSegments = getUsedTimeSegments(fieldNode);
212
+ for (const part of usedSegments) {
213
+ if (segmentValues[part] === null)
214
+ return false;
215
+ }
216
+ return true;
217
+ }
218
+ /**
219
+ * Infer the granularity to use based on the
220
+ * value and granularity props.
221
+ */
222
+ export function inferTimeGranularity(granularity) {
223
+ if (granularity)
224
+ return granularity;
225
+ return "minute";
226
+ }
227
+ /**
228
+ * Determines if the element with the provided id is the first focusable
229
+ * segment in the date field with the provided fieldId.
230
+ *
231
+ * @param id - The id of the element to check if it's the first segment
232
+ * @param fieldNode - The id of the date field associated with the segment
233
+ */
234
+ export function isFirstTimeSegment(id, fieldNode) {
235
+ if (!isBrowser)
236
+ return false;
237
+ const segments = getTimeSegments(fieldNode);
238
+ return segments.length ? segments[0].id === id : false;
239
+ }
240
+ /**
241
+ * Creates or updates a description element for a date field
242
+ * which enables screen readers to read the date field's value.
243
+ *
244
+ * This element is hidden from view, and is portalled to the body
245
+ * so it can be associated via `aria-describedby` and read by
246
+ * screen readers as the user interacts with the date field.
247
+ */
248
+ export function setTimeDescription(id, formatter, value) {
249
+ if (!isBrowser)
250
+ return;
251
+ const valueString = formatter.selectedTime(value);
252
+ const el = document.getElementById(id);
253
+ if (!el) {
254
+ const div = document.createElement("div");
255
+ div.style.cssText = styleToString({
256
+ display: "none",
257
+ });
258
+ div.id = id;
259
+ div.innerText = `Selected Time: ${valueString}`;
260
+ document.body.appendChild(div);
261
+ }
262
+ else {
263
+ el.innerText = `Selected Time: ${valueString}`;
264
+ }
265
+ }
266
+ /**
267
+ * Removes the description element for the date field with
268
+ * the provided ID. This function should be called when the
269
+ * date field is unmounted.
270
+ */
271
+ export function removeTimeDescriptionElement(id) {
272
+ if (!isBrowser)
273
+ return;
274
+ const el = document.getElementById(id);
275
+ if (!el)
276
+ return;
277
+ document.body.removeChild(el);
278
+ }
279
+ export function convertTimeValueToDateValue(time) {
280
+ if (time instanceof Time) {
281
+ return new CalendarDateTime(2020, 1, 1, time.hour, time.minute, time.second, time.millisecond);
282
+ }
283
+ return time;
284
+ }
285
+ export function convertTimeValueToTime(time) {
286
+ if (time instanceof Time)
287
+ return time;
288
+ return new Time(time.hour, time.minute, time.second, time.millisecond);
289
+ }
290
+ export function isTimeBefore(timeToCompare, referenceTime) {
291
+ return timeToCompare.compare(referenceTime) < 0;
292
+ }
293
+ export function isTimeAfter(timeToCompare, referenceTime) {
294
+ return timeToCompare.compare(referenceTime) > 0;
295
+ }
296
+ export function getISOTimeValue(time) {
297
+ if (time instanceof Time) {
298
+ return Time.toString();
299
+ }
300
+ return new Time(time.hour, time.minute, time.second, time.millisecond).toString();
301
+ }
@@ -1,6 +1,6 @@
1
- import type { DATE_SEGMENT_PARTS, EDITABLE_SEGMENT_PARTS, NON_EDITABLE_SEGMENT_PARTS, TIME_SEGMENT_PARTS } from "./parts.js";
1
+ import type { DATE_SEGMENT_PARTS, EDITABLE_SEGMENT_PARTS, NON_EDITABLE_SEGMENT_PARTS, EDITABLE_TIME_SEGMENT_PARTS } from "./parts.js";
2
2
  export type DateSegmentPart = (typeof DATE_SEGMENT_PARTS)[number];
3
- export type TimeSegmentPart = (typeof TIME_SEGMENT_PARTS)[number];
3
+ export type TimeSegmentPart = (typeof EDITABLE_TIME_SEGMENT_PARTS)[number];
4
4
  export type EditableSegmentPart = (typeof EDITABLE_SEGMENT_PARTS)[number];
5
5
  export type NonEditableSegmentPart = (typeof NON_EDITABLE_SEGMENT_PARTS)[number];
6
6
  export type SegmentPart = EditableSegmentPart | NonEditableSegmentPart;
@@ -1,6 +1,7 @@
1
1
  import { type DateValue } from "@internationalized/date";
2
- import type { HourCycle } from "../../shared/date/types.js";
2
+ import type { HourCycle, TimeValue } from "../../shared/date/types.js";
3
3
  export type Formatter = ReturnType<typeof createFormatter>;
4
+ export type TimeFormatter = ReturnType<typeof createTimeFormatter>;
4
5
  /**
5
6
  * Creates a wrapper around the `DateFormatter`, which is
6
7
  * an improved version of the {@link Intl.DateTimeFormat} API,
@@ -22,3 +23,12 @@ export declare function createFormatter(initialLocale: string): {
22
23
  selectedDate: (date: DateValue, includeTime?: boolean) => string;
23
24
  dayOfWeek: (date: Date, length?: Intl.DateTimeFormatOptions["weekday"]) => string;
24
25
  };
26
+ export declare function createTimeFormatter(initialLocale: string): {
27
+ setLocale: (newLocale: string) => void;
28
+ getLocale: () => string;
29
+ toParts: (timeValue: TimeValue, options?: Intl.DateTimeFormatOptions) => Intl.DateTimeFormatPart[];
30
+ custom: (date: Date, options: Intl.DateTimeFormatOptions) => string;
31
+ part: (dateObj: TimeValue, type: Intl.DateTimeFormatPartTypes, options?: Intl.DateTimeFormatOptions) => string;
32
+ dayPeriod: (date: Date, hourCycle?: HourCycle | undefined) => "AM" | "PM";
33
+ selectedTime: (date: TimeValue) => string;
34
+ };
@@ -1,5 +1,6 @@
1
1
  import { DateFormatter } from "@internationalized/date";
2
2
  import { hasTime, isZonedDateTime, toDate } from "./utils.js";
3
+ import { convertTimeValueToDateValue } from "./field/time-helpers.js";
3
4
  const defaultPartOptions = {
4
5
  year: "numeric",
5
6
  month: "numeric",
@@ -95,3 +96,58 @@ export function createFormatter(initialLocale) {
95
96
  dayOfWeek,
96
97
  };
97
98
  }
99
+ export function createTimeFormatter(initialLocale) {
100
+ let locale = initialLocale;
101
+ function setLocale(newLocale) {
102
+ locale = newLocale;
103
+ }
104
+ function getLocale() {
105
+ return locale;
106
+ }
107
+ function custom(date, options) {
108
+ return new DateFormatter(locale, options).format(date);
109
+ }
110
+ function selectedTime(date) {
111
+ return custom(toDate(convertTimeValueToDateValue(date)), {
112
+ timeStyle: "long",
113
+ });
114
+ }
115
+ function toParts(timeValue, options) {
116
+ const dateValue = convertTimeValueToDateValue(timeValue);
117
+ if (isZonedDateTime(dateValue)) {
118
+ return new DateFormatter(locale, {
119
+ ...options,
120
+ timeZone: dateValue.timeZone,
121
+ }).formatToParts(toDate(dateValue));
122
+ }
123
+ else {
124
+ return new DateFormatter(locale, options).formatToParts(toDate(dateValue));
125
+ }
126
+ }
127
+ function dayPeriod(date, hourCycle = undefined) {
128
+ const parts = new DateFormatter(locale, {
129
+ hour: "numeric",
130
+ minute: "numeric",
131
+ hourCycle: hourCycle === 24 ? "h23" : undefined,
132
+ }).formatToParts(date);
133
+ const value = parts.find((p) => p.type === "dayPeriod")?.value;
134
+ if (value === "PM")
135
+ return "PM";
136
+ return "AM";
137
+ }
138
+ function part(dateObj, type, options = {}) {
139
+ const opts = { ...defaultPartOptions, ...options };
140
+ const parts = toParts(dateObj, opts);
141
+ const part = parts.find((p) => p.type === type);
142
+ return part ? part.value : "";
143
+ }
144
+ return {
145
+ setLocale,
146
+ getLocale,
147
+ toParts,
148
+ custom,
149
+ part,
150
+ dayPeriod,
151
+ selectedTime,
152
+ };
153
+ }
@@ -1,9 +1,13 @@
1
1
  import { CalendarDateTime, type DateValue, ZonedDateTime } from "@internationalized/date";
2
- import type { DateMatcher, Granularity } from "../../shared/date/types.js";
2
+ import type { DateMatcher, Granularity, TimeGranularity, TimeValue } from "../../shared/date/types.js";
3
3
  type GetDefaultDateProps = {
4
4
  defaultValue?: DateValue | DateValue[] | undefined;
5
5
  granularity?: Granularity;
6
6
  };
7
+ type GetDefaultTimeProps = {
8
+ defaultValue?: TimeValue | undefined;
9
+ granularity?: TimeGranularity;
10
+ };
7
11
  /**
8
12
  * A helper function used throughout the various date builders
9
13
  * to generate a default `DateValue` using the `defaultValue`,
@@ -15,6 +19,7 @@ type GetDefaultDateProps = {
15
19
  *
16
20
  */
17
21
  export declare function getDefaultDate(opts: GetDefaultDateProps): DateValue;
22
+ export declare function getDefaultTime(opts: GetDefaultTimeProps): TimeValue;
18
23
  /**
19
24
  * Given a date string and a reference `DateValue` object, parse the
20
25
  * string to the same type as the reference object.
@@ -31,7 +36,7 @@ export declare function parseStringToDateValue(dateStr: string, referenceVal: Da
31
36
  export declare function toDate(dateValue: DateValue, tz?: string): Date;
32
37
  export declare function getDateValueType(date: DateValue): string;
33
38
  export declare function parseAnyDateValue(value: string, type: string): DateValue;
34
- export declare function isZonedDateTime(dateValue: DateValue): dateValue is ZonedDateTime;
39
+ export declare function isZonedDateTime(dateValue: DateValue | TimeValue): dateValue is ZonedDateTime;
35
40
  export declare function hasTime(dateValue: DateValue): dateValue is CalendarDateTime | ZonedDateTime;
36
41
  /**
37
42
  * Given a date, return the number of days in the month.
@@ -1,8 +1,12 @@
1
- import { CalendarDate, CalendarDateTime, ZonedDateTime, getDayOfWeek, getLocalTimeZone, parseDate, parseDateTime, parseZonedDateTime, toCalendar, } from "@internationalized/date";
1
+ import { CalendarDate, CalendarDateTime, Time, ZonedDateTime, getDayOfWeek, getLocalTimeZone, parseDate, parseDateTime, parseZonedDateTime, toCalendar, } from "@internationalized/date";
2
2
  const defaultDateDefaults = {
3
3
  defaultValue: undefined,
4
4
  granularity: "day",
5
5
  };
6
+ const defaultTimeDefaults = {
7
+ defaultValue: undefined,
8
+ granularity: "minute",
9
+ };
6
10
  /**
7
11
  * A helper function used throughout the various date builders
8
12
  * to generate a default `DateValue` using the `defaultValue`,
@@ -34,6 +38,16 @@ export function getDefaultDate(opts) {
34
38
  return new CalendarDate(year, month, day);
35
39
  }
36
40
  }
41
+ export function getDefaultTime(opts) {
42
+ const withDefaults = { ...defaultTimeDefaults, ...opts };
43
+ const { defaultValue } = withDefaults;
44
+ if (defaultValue) {
45
+ return defaultValue;
46
+ }
47
+ else {
48
+ return new Time(0, 0, 0);
49
+ }
50
+ }
37
51
  /**
38
52
  * Given a date string and a reference `DateValue` object, parse the
39
53
  * string to the same type as the reference object.
@@ -0,0 +1,9 @@
1
+ import type { Box } from "svelte-toolbelt";
2
+ export declare class DOMContext {
3
+ readonly element: Box<HTMLElement | null>;
4
+ readonly root: Document | ShadowRoot | null;
5
+ constructor(element: Box<HTMLElement | null>);
6
+ querySelector: (selector: string) => Element | null;
7
+ querySelectorAll: (selector: string) => NodeListOf<Element>;
8
+ getElementById: (id: string) => HTMLElement | null;
9
+ }
@@ -0,0 +1,26 @@
1
+ export class DOMContext {
2
+ element;
3
+ root = $derived.by(() => {
4
+ if (!this.element.current)
5
+ return null;
6
+ return this.element.current.getRootNode();
7
+ });
8
+ constructor(element) {
9
+ this.element = element;
10
+ }
11
+ querySelector = (selector) => {
12
+ if (!this.root)
13
+ return null;
14
+ return this.root.querySelector(selector);
15
+ };
16
+ querySelectorAll = (selector) => {
17
+ if (!this.root)
18
+ return [];
19
+ return this.root.querySelectorAll(selector);
20
+ };
21
+ getElementById = (id) => {
22
+ if (!this.root)
23
+ return null;
24
+ return this.root.getElementById(id);
25
+ };
26
+ }
@@ -1,4 +1,4 @@
1
- import { type ReadableBox } from "svelte-toolbelt";
1
+ import { type Box, type ReadableBox } from "svelte-toolbelt";
2
2
  import type { Orientation } from "../shared/index.js";
3
3
  type UseRovingFocusProps = ({
4
4
  /**
@@ -16,7 +16,7 @@ type UseRovingFocusProps = ({
16
16
  /**
17
17
  * The id of the root node
18
18
  */
19
- rootNodeId: ReadableBox<string>;
19
+ rootNode: Box<HTMLElement | null>;
20
20
  /**
21
21
  * Whether to loop through the candidates when reaching the end.
22
22
  */
@@ -32,7 +32,7 @@ type UseRovingFocusProps = ({
32
32
  onCandidateFocus?: (node: HTMLElement) => void;
33
33
  };
34
34
  export type UseRovingFocusReturn = ReturnType<typeof useRovingFocus>;
35
- export declare function useRovingFocus(props: UseRovingFocusProps): {
35
+ export declare function useRovingFocus(opts: UseRovingFocusProps): {
36
36
  setCurrentTabStopId(id: string): void;
37
37
  getTabIndex: (node: HTMLElement | null | undefined) => 0 | -1;
38
38
  handleKeydown: (node: HTMLElement | null | undefined, e: KeyboardEvent, both?: boolean) => HTMLElement | undefined;
@@ -3,20 +3,19 @@ import { getElemDirection } from "./locale.js";
3
3
  import { getDirectionalKeys } from "./get-directional-keys.js";
4
4
  import { kbd } from "./kbd.js";
5
5
  import { isBrowser } from "./is.js";
6
- export function useRovingFocus(props) {
6
+ export function useRovingFocus(opts) {
7
7
  const currentTabStopId = box(null);
8
8
  function getCandidateNodes() {
9
9
  if (!isBrowser)
10
10
  return [];
11
- const node = document.getElementById(props.rootNodeId.current);
12
- if (!node)
11
+ if (!opts.rootNode.current)
13
12
  return [];
14
- if (props.candidateSelector) {
15
- const candidates = Array.from(node.querySelectorAll(props.candidateSelector));
13
+ if (opts.candidateSelector) {
14
+ const candidates = Array.from(opts.rootNode.current.querySelectorAll(opts.candidateSelector));
16
15
  return candidates;
17
16
  }
18
- else if (props.candidateAttr) {
19
- const candidates = Array.from(node.querySelectorAll(`[${props.candidateAttr}]:not([data-disabled])`));
17
+ else if (opts.candidateAttr) {
18
+ const candidates = Array.from(opts.rootNode.current.querySelectorAll(`[${opts.candidateAttr}]:not([data-disabled])`));
20
19
  return candidates;
21
20
  }
22
21
  return [];
@@ -28,7 +27,7 @@ export function useRovingFocus(props) {
28
27
  items[0]?.focus();
29
28
  }
30
29
  function handleKeydown(node, e, both = false) {
31
- const rootNode = document.getElementById(props.rootNodeId.current);
30
+ const rootNode = opts.rootNode.current;
32
31
  if (!rootNode || !node)
33
32
  return;
34
33
  const items = getCandidateNodes();
@@ -36,8 +35,8 @@ export function useRovingFocus(props) {
36
35
  return;
37
36
  const currentIndex = items.indexOf(node);
38
37
  const dir = getElemDirection(rootNode);
39
- const { nextKey, prevKey } = getDirectionalKeys(dir, props.orientation.current);
40
- const loop = props.loop.current;
38
+ const { nextKey, prevKey } = getDirectionalKeys(dir, opts.orientation.current);
39
+ const loop = opts.loop.current;
41
40
  const keyToIndex = {
42
41
  [nextKey]: currentIndex + 1,
43
42
  [prevKey]: currentIndex - 1,
@@ -65,7 +64,7 @@ export function useRovingFocus(props) {
65
64
  return;
66
65
  itemToFocus.focus();
67
66
  currentTabStopId.current = itemToFocus.id;
68
- props.onCandidateFocus?.(itemToFocus);
67
+ opts.onCandidateFocus?.(itemToFocus);
69
68
  return itemToFocus;
70
69
  }
71
70
  function getTabIndex(node) {
@@ -1,9 +1,12 @@
1
- import type { DateValue } from "@internationalized/date";
2
- import type { DATE_SEGMENT_PARTS, EDITABLE_SEGMENT_PARTS, NON_EDITABLE_SEGMENT_PARTS, TIME_SEGMENT_PARTS } from "../../internal/date-time/field/parts.js";
1
+ import type { CalendarDateTime, DateValue, Time, ZonedDateTime } from "@internationalized/date";
2
+ import type { DATE_SEGMENT_PARTS, EDITABLE_SEGMENT_PARTS, NON_EDITABLE_SEGMENT_PARTS, EDITABLE_TIME_SEGMENT_PARTS } from "../../internal/date-time/field/parts.js";
3
3
  export type Granularity = "day" | "hour" | "minute" | "second";
4
+ export type TimeGranularity = "hour" | "minute" | "second";
4
5
  export type HourCycle = 12 | 24;
5
6
  export type WeekStartsOn = 0 | 1 | 2 | 3 | 4 | 5 | 6;
6
7
  export type DateMatcher = (date: DateValue) => boolean;
8
+ export type TimeValue = Time | CalendarDateTime | ZonedDateTime;
9
+ export type TimeValidator<T extends TimeValue> = (time: T) => string[] | string | void;
7
10
  /**
8
11
  * A function that returns a string or array of strings as validation errors if the date is
9
12
  * invalid, or nothing if the date is valid
@@ -17,15 +20,28 @@ export type DateRangeValidator = (range: {
17
20
  start: DateValue;
18
21
  end: DateValue;
19
22
  }) => string[] | string | void;
23
+ export type TimeRangeValidator<T extends TimeValue = Time> = (range: {
24
+ start: T;
25
+ end: T;
26
+ }) => string[] | string | void;
20
27
  /**
21
28
  * A callback fired when the date field's value is invalid. Use this to display an error
22
29
  * message to the user.
23
30
  */
24
31
  export type DateOnInvalid = (reason: "min" | "max" | "custom", msg?: string | string[]) => void;
32
+ /**
33
+ * A callback fired when the time field's value is invalid. Use this to display an error
34
+ * message to the user.
35
+ */
36
+ export type TimeOnInvalid = (reason: "min" | "max" | "custom", msg?: string | string[]) => void;
25
37
  export type DateRange = {
26
38
  start: DateValue | undefined;
27
39
  end: DateValue | undefined;
28
40
  };
41
+ export type TimeRange<T extends TimeValue = Time> = {
42
+ start: T | undefined;
43
+ end: T | undefined;
44
+ };
29
45
  export type Month<T> = {
30
46
  /**
31
47
  * A `DateValue` used to represent the month. Since days
@@ -52,21 +68,25 @@ export type Month<T> = {
52
68
  dates: T[];
53
69
  };
54
70
  export type DateSegmentPart = (typeof DATE_SEGMENT_PARTS)[number];
55
- export type TimeSegmentPart = (typeof TIME_SEGMENT_PARTS)[number];
71
+ export type EditableTimeSegmentPart = (typeof EDITABLE_TIME_SEGMENT_PARTS)[number];
56
72
  export type EditableSegmentPart = (typeof EDITABLE_SEGMENT_PARTS)[number];
57
73
  export type NonEditableSegmentPart = (typeof NON_EDITABLE_SEGMENT_PARTS)[number];
58
74
  export type SegmentPart = EditableSegmentPart | NonEditableSegmentPart;
75
+ export type TimeSegmentPart = EditableTimeSegmentPart | "literal";
76
+ export type AnyTimeExceptLiteral = Exclude<TimeSegmentPart, "literal">;
59
77
  export type AnyExceptLiteral = Exclude<SegmentPart, "literal">;
60
78
  export type DayPeriod = "AM" | "PM" | null;
61
79
  export type DateSegmentObj = {
62
80
  [K in DateSegmentPart]: string | null;
63
81
  };
64
82
  export type TimeSegmentObj = {
65
- [K in TimeSegmentPart]: K extends "dayPeriod" ? DayPeriod : string | null;
83
+ [K in EditableTimeSegmentPart]: K extends "dayPeriod" ? DayPeriod : string | null;
66
84
  };
67
85
  export type DateAndTimeSegmentObj = DateSegmentObj & TimeSegmentObj;
68
86
  export type SegmentValueObj = DateSegmentObj | DateAndTimeSegmentObj;
69
87
  export type SegmentContentObj = Record<EditableSegmentPart, string>;
88
+ export type TimeSegmentValueObj = TimeSegmentObj;
89
+ export type TimeSegmentContentObj = Record<EditableTimeSegmentPart, string>;
70
90
  export type SegmentState = {
71
91
  lastKeyZero: boolean;
72
92
  hasLeftFocus: boolean;
@@ -75,3 +95,6 @@ export type SegmentState = {
75
95
  export type SegmentStateMap = {
76
96
  [K in EditableSegmentPart]: SegmentState;
77
97
  };
98
+ export type TimeSegmentStateMap = {
99
+ [K in EditableTimeSegmentPart]: SegmentState;
100
+ };
@@ -29,8 +29,8 @@ export type WithoutChild<T> = T extends {
29
29
  export type WithElementRef<T, U extends HTMLElement = HTMLElement> = T & {
30
30
  ref?: U | null;
31
31
  };
32
- export type { EditableSegmentPart } from "./date/types.js";
33
- export type { Month, DateMatcher, DateOnInvalid, DateRangeValidator, DateValidator, DateRange, } from "./date/types.js";
32
+ export type { EditableSegmentPart, EditableTimeSegmentPart } from "./date/types.js";
33
+ export type { Month, DateMatcher, DateOnInvalid, DateRangeValidator, DateValidator, DateRange, TimeValue, TimeSegmentPart, TimeRange, TimeValidator, TimeRangeValidator, TimeOnInvalid, } from "./date/types.js";
34
34
  export type { WithChild, Without, WithChildren } from "../internal/types.js";
35
35
  export { mergeProps } from "svelte-toolbelt";
36
36
  export { useId } from "../internal/use-id.js";
package/dist/types.d.ts CHANGED
@@ -33,6 +33,8 @@ export type * from "./bits/separator/types.js";
33
33
  export type * from "./bits/slider/types.js";
34
34
  export type * from "./bits/switch/types.js";
35
35
  export type * from "./bits/tabs/types.js";
36
+ export type * from "./bits/time-field/types.js";
37
+ export type * from "./bits/time-range-field/types.js";
36
38
  export type * from "./bits/toggle/types.js";
37
39
  export type * from "./bits/toggle-group/types.js";
38
40
  export type * from "./bits/toolbar/types.js";