@sjvair/monitor-map 3.0.3 → 3.0.5

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 (279) hide show
  1. package/dist/lib/LoadScreen.svelte +68 -0
  2. package/dist/lib/LoadScreen.svelte.d.ts +25 -0
  3. package/dist/lib/MainMapView.svelte +1 -0
  4. package/dist/lib/MainMapView.svelte.d.ts +26 -0
  5. package/dist/lib/MapLegend.svelte +15 -0
  6. package/dist/lib/MapLegend.svelte.d.ts +18 -0
  7. package/dist/lib/MonitorDetailPanel.svelte +152 -0
  8. package/dist/lib/MonitorDetailPanel.svelte.d.ts +3 -0
  9. package/dist/lib/MonitorMapLayout.svelte +193 -0
  10. package/dist/lib/MonitorMapLayout.svelte.d.ts +7 -0
  11. package/dist/lib/actions.d.ts +3 -0
  12. package/dist/lib/actions.js +12 -8
  13. package/dist/lib/assets/icons/adjustment-horizontal.svg +3 -0
  14. package/dist/lib/assets/logos/airgradient-blue.svg +63 -0
  15. package/dist/lib/assets/logos/airnow-compact.jpg +0 -0
  16. package/dist/lib/assets/logos/carb-compact.jpg +0 -0
  17. package/dist/lib/assets/logos/purpleair-compact.png +0 -0
  18. package/dist/lib/assets/logos/sjvair-parts/sjvair-air.webp +0 -0
  19. package/dist/lib/assets/logos/sjvair-parts/sjvair-icon.webp +0 -0
  20. package/dist/lib/assets/logos/sjvair-parts/sjvair-sjv.webp +0 -0
  21. package/dist/lib/assets/logos/sjvair-white.svg +115 -0
  22. package/dist/lib/assets/logos/sjvair.svg +96 -0
  23. package/dist/lib/collocation-sites/CollocationTooltip.svelte +98 -0
  24. package/dist/lib/collocation-sites/CollocationTooltip.svelte.d.ts +7 -0
  25. package/dist/lib/collocation-sites/collocation-utils.d.ts +3 -0
  26. package/dist/lib/collocation-sites/collocation-utils.js +30 -0
  27. package/dist/lib/collocation-sites/collocations-icon-manager.svelte.d.ts +7 -0
  28. package/dist/lib/collocation-sites/collocations-icon-manager.svelte.js +17 -20
  29. package/dist/lib/collocation-sites/collocations-map-integration.svelte.d.ts +18 -0
  30. package/dist/lib/collocation-sites/collocations-map-integration.svelte.js +98 -83
  31. package/dist/lib/collocation-sites/collocations.svelte.d.ts +9 -0
  32. package/dist/lib/collocation-sites/collocations.svelte.js +17 -26
  33. package/dist/lib/collocation-sites/types.d.ts +8 -0
  34. package/dist/lib/collocation-sites/types.js +1 -0
  35. package/dist/lib/colors.d.ts +17 -0
  36. package/dist/lib/colors.js +29 -23
  37. package/dist/lib/components/DataBox.svelte +29 -0
  38. package/dist/lib/components/DataBox.svelte.d.ts +9 -0
  39. package/dist/lib/components/DisplayOption.svelte +7 -0
  40. package/dist/lib/components/DisplayOption.svelte.d.ts +5 -0
  41. package/dist/lib/components/MapLayersDisplayOptions.svelte +42 -0
  42. package/dist/lib/components/MapLayersDisplayOptions.svelte.d.ts +18 -0
  43. package/dist/lib/components/SegmentedControl.svelte +61 -0
  44. package/dist/lib/components/SegmentedControl.svelte.d.ts +11 -0
  45. package/dist/lib/components/ToggleSwitch.svelte +93 -0
  46. package/dist/lib/components/ToggleSwitch.svelte.d.ts +9 -0
  47. package/dist/lib/components/ui/button/button.svelte +89 -0
  48. package/dist/lib/components/ui/button/button.svelte.d.ts +70 -0
  49. package/dist/lib/components/ui/button/index.d.ts +2 -0
  50. package/dist/lib/components/ui/button/index.js +4 -0
  51. package/dist/lib/components/ui/range-calendar/index.d.ts +19 -0
  52. package/dist/lib/components/ui/range-calendar/index.js +21 -0
  53. package/dist/lib/components/ui/range-calendar/range-calendar-caption.svelte +76 -0
  54. package/dist/lib/components/ui/range-calendar/range-calendar-caption.svelte.d.ts +19 -0
  55. package/dist/lib/components/ui/range-calendar/range-calendar-cell.svelte +19 -0
  56. package/dist/lib/components/ui/range-calendar/range-calendar-cell.svelte.d.ts +4 -0
  57. package/dist/lib/components/ui/range-calendar/range-calendar-day.svelte +36 -0
  58. package/dist/lib/components/ui/range-calendar/range-calendar-day.svelte.d.ts +4 -0
  59. package/dist/lib/components/ui/range-calendar/range-calendar-grid-body.svelte +7 -0
  60. package/dist/lib/components/ui/range-calendar/range-calendar-grid-body.svelte.d.ts +4 -0
  61. package/dist/lib/components/ui/range-calendar/range-calendar-grid-head.svelte +7 -0
  62. package/dist/lib/components/ui/range-calendar/range-calendar-grid-head.svelte.d.ts +4 -0
  63. package/dist/lib/components/ui/range-calendar/range-calendar-grid-row.svelte +12 -0
  64. package/dist/lib/components/ui/range-calendar/range-calendar-grid-row.svelte.d.ts +4 -0
  65. package/dist/lib/components/ui/range-calendar/range-calendar-grid.svelte +16 -0
  66. package/dist/lib/components/ui/range-calendar/range-calendar-grid.svelte.d.ts +4 -0
  67. package/dist/lib/components/ui/range-calendar/range-calendar-head-cell.svelte +19 -0
  68. package/dist/lib/components/ui/range-calendar/range-calendar-head-cell.svelte.d.ts +4 -0
  69. package/dist/lib/components/ui/range-calendar/range-calendar-header.svelte +19 -0
  70. package/dist/lib/components/ui/range-calendar/range-calendar-header.svelte.d.ts +4 -0
  71. package/dist/lib/components/ui/range-calendar/range-calendar-heading.svelte +16 -0
  72. package/dist/lib/components/ui/range-calendar/range-calendar-heading.svelte.d.ts +4 -0
  73. package/dist/lib/components/ui/range-calendar/range-calendar-month-select.svelte +44 -0
  74. package/dist/lib/components/ui/range-calendar/range-calendar-month-select.svelte.d.ts +4 -0
  75. package/dist/lib/components/ui/range-calendar/range-calendar-month.svelte +15 -0
  76. package/dist/lib/components/ui/range-calendar/range-calendar-month.svelte.d.ts +5 -0
  77. package/dist/lib/components/ui/range-calendar/range-calendar-months.svelte +19 -0
  78. package/dist/lib/components/ui/range-calendar/range-calendar-months.svelte.d.ts +5 -0
  79. package/dist/lib/components/ui/range-calendar/range-calendar-nav.svelte +19 -0
  80. package/dist/lib/components/ui/range-calendar/range-calendar-nav.svelte.d.ts +5 -0
  81. package/dist/lib/components/ui/range-calendar/range-calendar-next-button.svelte +36 -0
  82. package/dist/lib/components/ui/range-calendar/range-calendar-next-button.svelte.d.ts +8 -0
  83. package/dist/lib/components/ui/range-calendar/range-calendar-prev-button.svelte +36 -0
  84. package/dist/lib/components/ui/range-calendar/range-calendar-prev-button.svelte.d.ts +8 -0
  85. package/dist/lib/components/ui/range-calendar/range-calendar-year-select.svelte +43 -0
  86. package/dist/lib/components/ui/range-calendar/range-calendar-year-select.svelte.d.ts +4 -0
  87. package/dist/lib/components/ui/range-calendar/range-calendar.svelte +112 -0
  88. package/dist/lib/components/ui/range-calendar/range-calendar.svelte.d.ts +21 -0
  89. package/dist/lib/data-chart/DataChart.svelte +303 -0
  90. package/dist/lib/data-chart/DataChart.svelte.d.ts +7 -0
  91. package/dist/lib/data-chart/DateRange.d.ts +6 -0
  92. package/dist/lib/data-chart/DateRange.js +15 -14
  93. package/dist/lib/data-chart/chart-utils.d.ts +3 -0
  94. package/dist/lib/data-chart/chart-utils.js +157 -93
  95. package/dist/lib/data-chart/data-chart.svelte.d.ts +7 -0
  96. package/dist/lib/data-chart/data-chart.svelte.js +7 -28
  97. package/dist/lib/data-chart/requests.d.ts +3 -0
  98. package/dist/lib/data-chart/requests.js +36 -28
  99. package/dist/lib/data-chart/tooltip.d.ts +10 -0
  100. package/dist/lib/data-chart/tooltip.js +160 -98
  101. package/dist/lib/ev-stations/components/EvStationClusterTooltip.svelte +16 -0
  102. package/dist/lib/ev-stations/components/EvStationClusterTooltip.svelte.d.ts +7 -0
  103. package/dist/lib/ev-stations/components/EvStationTooltip.svelte +127 -0
  104. package/dist/lib/ev-stations/components/EvStationTooltip.svelte.d.ts +7 -0
  105. package/dist/lib/ev-stations/components/EvStationsDisplayOptions.svelte +46 -0
  106. package/dist/lib/ev-stations/components/EvStationsDisplayOptions.svelte.d.ts +18 -0
  107. package/dist/lib/ev-stations/data-maps.d.ts +5 -0
  108. package/dist/lib/ev-stations/data-maps.js +152 -4
  109. package/dist/lib/ev-stations/ev-station-icons.d.ts +16 -0
  110. package/dist/lib/ev-stations/ev-station-icons.js +21 -27
  111. package/dist/lib/ev-stations/ev-stations-cluster-renderer.d.ts +19 -0
  112. package/dist/lib/ev-stations/ev-stations-cluster-renderer.js +130 -117
  113. package/dist/lib/ev-stations/ev-stations-map-integration.svelte.d.ts +31 -0
  114. package/dist/lib/ev-stations/ev-stations-map-integration.svelte.js +206 -180
  115. package/dist/lib/ev-stations/ev-stations.svelte.d.ts +9 -0
  116. package/dist/lib/ev-stations/ev-stations.svelte.js +54 -32
  117. package/dist/lib/ev-stations/types.d.ts +53 -0
  118. package/dist/lib/ev-stations/types.js +1 -0
  119. package/dist/lib/ev-stations/zip-codes.d.ts +13 -0
  120. package/dist/lib/ev-stations/zip-codes.js +457 -135
  121. package/dist/lib/hms/components/HMSFireLegend.svelte +21 -0
  122. package/dist/lib/hms/components/HMSFireLegend.svelte.d.ts +18 -0
  123. package/dist/lib/hms/hms-fire-icon-manager.d.ts +5 -0
  124. package/dist/lib/hms/hms-fire-icon-manager.js +28 -37
  125. package/dist/lib/hms/hms-fire-map-integration.svelte.d.ts +23 -0
  126. package/dist/lib/hms/hms-fire-map-integration.svelte.js +94 -97
  127. package/dist/lib/hms/hms-smoke-map-integration.svelte.d.ts +19 -0
  128. package/dist/lib/hms/hms-smoke-map-integration.svelte.js +68 -84
  129. package/dist/lib/hms/hms.svelte.d.ts +19 -0
  130. package/dist/lib/hms/hms.svelte.js +225 -76
  131. package/dist/lib/index.d.ts +68 -0
  132. package/dist/lib/index.js +56 -21
  133. package/dist/lib/map/Map.svelte +13 -0
  134. package/dist/lib/map/Map.svelte.d.ts +8 -0
  135. package/dist/lib/map/MapStyleDisplayOptions.svelte +61 -0
  136. package/dist/lib/map/MapStyleDisplayOptions.svelte.d.ts +3 -0
  137. package/dist/lib/map/Menu.svelte +64 -0
  138. package/dist/lib/map/Menu.svelte.d.ts +5 -0
  139. package/dist/lib/map/icons.d.ts +7 -0
  140. package/dist/lib/map/icons.js +24 -22
  141. package/dist/lib/map/integrations/base-layer-seperator.d.ts +9 -0
  142. package/dist/lib/map/integrations/base-layer-seperator.js +11 -12
  143. package/dist/lib/map/integrations/click-manager.d.ts +14 -0
  144. package/dist/lib/map/integrations/click-manager.js +52 -33
  145. package/dist/lib/map/integrations/integrations-manager.d.ts +8 -0
  146. package/dist/lib/map/integrations/integrations-manager.js +20 -12
  147. package/dist/lib/map/integrations/map-display-option.svelte.d.ts +7 -0
  148. package/dist/lib/map/integrations/map-display-option.svelte.js +10 -18
  149. package/dist/lib/map/integrations/map-geojson-integration.svelte.d.ts +13 -0
  150. package/dist/lib/map/integrations/map-geojson-integration.svelte.js +21 -17
  151. package/dist/lib/map/integrations/map-icon-manager.d.ts +15 -0
  152. package/dist/lib/map/integrations/map-icon-manager.js +52 -46
  153. package/dist/lib/map/integrations/map-integration.svelte.d.ts +6 -0
  154. package/dist/lib/map/integrations/map-integration.svelte.js +2 -5
  155. package/dist/lib/map/integrations/map-layer-integration.svelte.d.ts +11 -0
  156. package/dist/lib/map/integrations/map-layer-integration.svelte.js +36 -23
  157. package/dist/lib/map/integrations/tooltip.svelte.d.ts +28 -0
  158. package/dist/lib/map/integrations/tooltip.svelte.js +120 -78
  159. package/dist/lib/map/integrations/types.d.ts +14 -0
  160. package/dist/lib/map/integrations/types.js +1 -0
  161. package/dist/lib/map/map.svelte.d.ts +14 -0
  162. package/dist/lib/map/map.svelte.js +48 -50
  163. package/dist/lib/map/utils.d.ts +7 -0
  164. package/dist/lib/map/utils.js +32 -29
  165. package/dist/lib/monitors/components/MonitorClusterTooltip.svelte +112 -0
  166. package/dist/lib/monitors/components/MonitorClusterTooltip.svelte.d.ts +7 -0
  167. package/dist/lib/monitors/components/MonitorMarkersLegend.svelte +41 -0
  168. package/dist/lib/monitors/components/MonitorMarkersLegend.svelte.d.ts +3 -0
  169. package/dist/lib/monitors/components/MonitorSubscriptionManager.svelte +128 -0
  170. package/dist/lib/monitors/components/MonitorSubscriptionManager.svelte.d.ts +6 -0
  171. package/dist/lib/monitors/components/MonitorTooltip.svelte +61 -0
  172. package/dist/lib/monitors/components/MonitorTooltip.svelte.d.ts +7 -0
  173. package/dist/lib/monitors/components/MonitorWidgetModal.svelte +100 -0
  174. package/dist/lib/monitors/components/MonitorWidgetModal.svelte.d.ts +6 -0
  175. package/dist/lib/monitors/components/MonitorsDisplayOptions.svelte +79 -0
  176. package/dist/lib/monitors/components/MonitorsDisplayOptions.svelte.d.ts +3 -0
  177. package/dist/lib/monitors/monitor-utils.d.ts +4 -0
  178. package/dist/lib/monitors/monitor-utils.js +33 -23
  179. package/dist/lib/monitors/monitors-cluster-renderer.d.ts +33 -0
  180. package/dist/lib/monitors/monitors-cluster-renderer.js +218 -209
  181. package/dist/lib/monitors/monitors-icon-manager.svelte.d.ts +13 -0
  182. package/dist/lib/monitors/monitors-icon-manager.svelte.js +75 -70
  183. package/dist/lib/monitors/monitors-map-integration.svelte.d.ts +40 -0
  184. package/dist/lib/monitors/monitors-map-integration.svelte.js +278 -270
  185. package/dist/lib/monitors/monitors.svelte.d.ts +16 -0
  186. package/dist/lib/monitors/monitors.svelte.js +38 -63
  187. package/dist/lib/monitors/types.d.ts +26 -0
  188. package/dist/lib/monitors/types.js +1 -0
  189. package/dist/lib/reactivity.svelte.d.ts +0 -0
  190. package/dist/lib/reactivity.svelte.js +83 -0
  191. package/dist/lib/router-context.d.ts +27 -0
  192. package/dist/lib/router-context.js +11 -11
  193. package/dist/lib/routes.d.ts +2 -0
  194. package/dist/lib/routes.js +10 -9
  195. package/dist/lib/search/Search.svelte +189 -0
  196. package/dist/lib/search/Search.svelte.d.ts +3 -0
  197. package/dist/lib/search/service.d.ts +17 -0
  198. package/dist/lib/search/service.js +75 -85
  199. package/dist/lib/utils.d.ts +13 -0
  200. package/dist/lib/utils.js +10 -12
  201. package/dist/lib/weather.d.ts +1 -0
  202. package/dist/lib/weather.js +11 -7
  203. package/dist/lib/wind/wind.svelte.d.ts +10 -0
  204. package/dist/lib/wind/wind.svelte.js +13 -21
  205. package/package.json +9 -7
  206. package/src/lib/LoadScreen.svelte +3 -3
  207. package/src/lib/hms/components/HMSFireLegend.svelte +1 -1
  208. package/src/lib/hms/hms.svelte.ts +8 -9
  209. package/src/lib/index.ts +18 -0
  210. package/src/lib/routes.ts +6 -1
  211. package/src/lib/utils.ts +1 -1
  212. package/dist/lib/LoadScreen.js +0 -73
  213. package/dist/lib/MainMapView.js +0 -7
  214. package/dist/lib/MapLegend.js +0 -13
  215. package/dist/lib/MonitorDetailPanel.js +0 -169
  216. package/dist/lib/MonitorMapLayout.js +0 -91
  217. package/dist/lib/_virtual/_rolldown/runtime.js +0 -11
  218. package/dist/lib/assets/logos/airgradient-blue.js +0 -4
  219. package/dist/lib/assets/logos/airnow-compact.js +0 -4
  220. package/dist/lib/assets/logos/carb-compact.js +0 -4
  221. package/dist/lib/assets/logos/purpleair-compact.js +0 -4
  222. package/dist/lib/assets/logos/sjvair.js +0 -4
  223. package/dist/lib/collocation-sites/CollocationTooltip.js +0 -105
  224. package/dist/lib/components/DataBox.js +0 -30
  225. package/dist/lib/components/DisplayOption.js +0 -10
  226. package/dist/lib/components/MapLayersDisplayOptions.js +0 -87
  227. package/dist/lib/components/SegmentedControl.js +0 -37
  228. package/dist/lib/components/ToggleSwitch.js +0 -17
  229. package/dist/lib/components/ui/button/button.js +0 -34
  230. package/dist/lib/components/ui/range-calendar/range-calendar-caption.js +0 -82
  231. package/dist/lib/components/ui/range-calendar/range-calendar-cell.js +0 -35
  232. package/dist/lib/components/ui/range-calendar/range-calendar-day.js +0 -35
  233. package/dist/lib/components/ui/range-calendar/range-calendar-grid-body.js +0 -27
  234. package/dist/lib/components/ui/range-calendar/range-calendar-grid-head.js +0 -27
  235. package/dist/lib/components/ui/range-calendar/range-calendar-grid-row.js +0 -35
  236. package/dist/lib/components/ui/range-calendar/range-calendar-grid.js +0 -35
  237. package/dist/lib/components/ui/range-calendar/range-calendar-head-cell.js +0 -35
  238. package/dist/lib/components/ui/range-calendar/range-calendar-header.js +0 -35
  239. package/dist/lib/components/ui/range-calendar/range-calendar-month-select.js +0 -61
  240. package/dist/lib/components/ui/range-calendar/range-calendar-month.js +0 -25
  241. package/dist/lib/components/ui/range-calendar/range-calendar-months.js +0 -25
  242. package/dist/lib/components/ui/range-calendar/range-calendar-nav.js +0 -25
  243. package/dist/lib/components/ui/range-calendar/range-calendar-next-button.js +0 -58
  244. package/dist/lib/components/ui/range-calendar/range-calendar-prev-button.js +0 -58
  245. package/dist/lib/components/ui/range-calendar/range-calendar-year-select.js +0 -59
  246. package/dist/lib/components/ui/range-calendar/range-calendar.js +0 -272
  247. package/dist/lib/data-chart/DataChart.js +0 -142
  248. package/dist/lib/ev-stations/components/EvStationClusterTooltip.js +0 -16
  249. package/dist/lib/ev-stations/components/EvStationTooltip.js +0 -120
  250. package/dist/lib/ev-stations/components/EvStationsDisplayOptions.js +0 -41
  251. package/dist/lib/hms/components/HMSFireLegend.js +0 -35
  252. package/dist/lib/map/Map.js +0 -14
  253. package/dist/lib/map/MapStyleDisplayOptions.js +0 -43
  254. package/dist/lib/map/Menu.js +0 -44
  255. package/dist/lib/monitors/components/MonitorClusterTooltip.js +0 -83
  256. package/dist/lib/monitors/components/MonitorMarkersLegend.js +0 -35
  257. package/dist/lib/monitors/components/MonitorSubscriptionManager.js +0 -104
  258. package/dist/lib/monitors/components/MonitorTooltip.js +0 -59
  259. package/dist/lib/monitors/components/MonitorWidgetModal.js +0 -40
  260. package/dist/lib/monitors/components/MonitorsDisplayOptions.js +0 -76
  261. package/dist/lib/search/Search.js +0 -124
  262. package/dist/lib/sjvair-air.avif +0 -0
  263. package/dist/lib/sjvair-air.png +0 -0
  264. package/dist/lib/sjvair-air.webp +0 -0
  265. package/dist/lib/sjvair-air2.avif +0 -0
  266. package/dist/lib/sjvair-air2.png +0 -0
  267. package/dist/lib/sjvair-air2.webp +0 -0
  268. package/dist/lib/sjvair-icon.avif +0 -0
  269. package/dist/lib/sjvair-icon.png +0 -0
  270. package/dist/lib/sjvair-icon.webp +0 -0
  271. package/dist/lib/sjvair-icon2.avif +0 -0
  272. package/dist/lib/sjvair-icon2.png +0 -0
  273. package/dist/lib/sjvair-icon2.webp +0 -0
  274. package/dist/lib/sjvair-sjv.avif +0 -0
  275. package/dist/lib/sjvair-sjv.png +0 -0
  276. package/dist/lib/sjvair-sjv.webp +0 -0
  277. package/dist/lib/sjvair-sjv2.avif +0 -0
  278. package/dist/lib/sjvair-sjv2.png +0 -0
  279. package/dist/lib/sjvair-sjv2.webp +0 -0
@@ -0,0 +1,112 @@
1
+ <script lang="ts">
2
+ import { RangeCalendar as RangeCalendarPrimitive } from "bits-ui";
3
+ import * as RangeCalendar from "./index.js";
4
+ import { cn, type WithoutChildrenOrChild } from "../../../utils.js";
5
+ import type { ButtonVariant } from "../button/index.js";
6
+ import type { Snippet } from "svelte";
7
+ import { isEqualMonth, type DateValue } from "@internationalized/date";
8
+
9
+ let {
10
+ ref = $bindable(null),
11
+ value = $bindable(),
12
+ placeholder = $bindable(),
13
+ weekdayFormat = "short",
14
+ class: className,
15
+ buttonVariant = "ghost",
16
+ captionLayout = "label",
17
+ locale = "en-US",
18
+ months: monthsProp,
19
+ years,
20
+ monthFormat: monthFormatProp,
21
+ yearFormat = "numeric",
22
+ day,
23
+ disableDaysOutsideMonth = false,
24
+ ...restProps
25
+ }: WithoutChildrenOrChild<RangeCalendarPrimitive.RootProps> & {
26
+ buttonVariant?: ButtonVariant;
27
+ captionLayout?: "dropdown" | "dropdown-months" | "dropdown-years" | "label";
28
+ months?: RangeCalendarPrimitive.MonthSelectProps["months"];
29
+ years?: RangeCalendarPrimitive.YearSelectProps["years"];
30
+ monthFormat?: RangeCalendarPrimitive.MonthSelectProps["monthFormat"];
31
+ yearFormat?: RangeCalendarPrimitive.YearSelectProps["yearFormat"];
32
+ day?: Snippet<[{ day: DateValue; outsideMonth: boolean }]>;
33
+ } = $props();
34
+
35
+ const monthFormat = $derived.by(() => {
36
+ if (monthFormatProp) return monthFormatProp;
37
+ if (captionLayout.startsWith("dropdown")) return "short";
38
+ return "long";
39
+ });
40
+ </script>
41
+
42
+ <RangeCalendarPrimitive.Root
43
+ bind:ref
44
+ bind:value
45
+ bind:placeholder
46
+ {weekdayFormat}
47
+ {disableDaysOutsideMonth}
48
+ class={cn(
49
+ "bg-background group/calendar p-2 p-3 [--cell-radius:var(--radius-md)] [--cell-size:--spacing(7)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
50
+ className
51
+ )}
52
+ {locale}
53
+ {monthFormat}
54
+ {yearFormat}
55
+ {...restProps}
56
+ >
57
+ {#snippet children({ months, weekdays })}
58
+ <RangeCalendar.Months>
59
+ <RangeCalendar.Nav>
60
+ <RangeCalendar.PrevButton variant={buttonVariant} />
61
+ <RangeCalendar.NextButton variant={buttonVariant} />
62
+ </RangeCalendar.Nav>
63
+ {#each months as month, monthIndex (month)}
64
+ <RangeCalendar.Month>
65
+ <RangeCalendar.Header>
66
+ <RangeCalendar.Caption
67
+ {captionLayout}
68
+ months={monthsProp}
69
+ {monthFormat}
70
+ {years}
71
+ {yearFormat}
72
+ month={month.value}
73
+ bind:placeholder
74
+ {locale}
75
+ {monthIndex}
76
+ />
77
+ </RangeCalendar.Header>
78
+
79
+ <RangeCalendar.Grid>
80
+ <RangeCalendar.GridHead>
81
+ <RangeCalendar.GridRow class="select-none">
82
+ {#each weekdays as weekday, i (i)}
83
+ <RangeCalendar.HeadCell>
84
+ {weekday.slice(0, 2)}
85
+ </RangeCalendar.HeadCell>
86
+ {/each}
87
+ </RangeCalendar.GridRow>
88
+ </RangeCalendar.GridHead>
89
+ <RangeCalendar.GridBody>
90
+ {#each month.weeks as weekDates (weekDates)}
91
+ <RangeCalendar.GridRow class="mt-2 w-full">
92
+ {#each weekDates as date (date)}
93
+ <RangeCalendar.Cell {date} month={month.value}>
94
+ {#if day}
95
+ {@render day({
96
+ day: date,
97
+ outsideMonth: !isEqualMonth(date, month.value)
98
+ })}
99
+ {:else}
100
+ <RangeCalendar.Day />
101
+ {/if}
102
+ </RangeCalendar.Cell>
103
+ {/each}
104
+ </RangeCalendar.GridRow>
105
+ {/each}
106
+ </RangeCalendar.GridBody>
107
+ </RangeCalendar.Grid>
108
+ </RangeCalendar.Month>
109
+ {/each}
110
+ </RangeCalendar.Months>
111
+ {/snippet}
112
+ </RangeCalendarPrimitive.Root>
@@ -0,0 +1,21 @@
1
+ import { RangeCalendar as RangeCalendarPrimitive } from "bits-ui";
2
+ import * as RangeCalendar from "./index.js";
3
+ import { type WithoutChildrenOrChild } from "../../../utils.js";
4
+ import type { ButtonVariant } from "../button/index.js";
5
+ import type { Snippet } from "svelte";
6
+ import { type DateValue } from "@internationalized/date";
7
+ type $$ComponentProps = WithoutChildrenOrChild<RangeCalendarPrimitive.RootProps> & {
8
+ buttonVariant?: ButtonVariant;
9
+ captionLayout?: "dropdown" | "dropdown-months" | "dropdown-years" | "label";
10
+ months?: RangeCalendarPrimitive.MonthSelectProps["months"];
11
+ years?: RangeCalendarPrimitive.YearSelectProps["years"];
12
+ monthFormat?: RangeCalendarPrimitive.MonthSelectProps["monthFormat"];
13
+ yearFormat?: RangeCalendarPrimitive.YearSelectProps["yearFormat"];
14
+ day?: Snippet<[{
15
+ day: DateValue;
16
+ outsideMonth: boolean;
17
+ }]>;
18
+ };
19
+ declare const RangeCalendar: import("svelte").Component<$$ComponentProps, {}, "value" | "ref" | "placeholder">;
20
+ type RangeCalendar = ReturnType<typeof RangeCalendar>;
21
+ export default RangeCalendar;
@@ -0,0 +1,303 @@
1
+ <script lang="ts">
2
+ import type { Attachment } from "svelte/attachments";
3
+ import type { MonitorLatestType } from "@sjvair/sdk";
4
+ import type { DateRange as CalendarRange } from "bits-ui";
5
+ import { parseAbsolute } from "@internationalized/date";
6
+ import { Maximize, SquareX } from "@lucide/svelte";
7
+ import uPlot from "uplot";
8
+ import { getMonitorEntriesCSVUrl } from "@sjvair/sdk/monitors";
9
+ import { format, parseISO } from "date-fns";
10
+ import { RangeCalendar } from "../components/ui/range-calendar";
11
+ import { DataChartManager } from "./data-chart.svelte.ts";
12
+ import { createDateRange } from "./DateRange.ts";
13
+ import { fetchChartData } from "./requests.ts";
14
+ import { getChartConfig } from "./chart-utils.ts";
15
+ import { monitorsManager } from "../monitors/monitors.svelte";
16
+
17
+ let { monitor }: { monitor: MonitorLatestType<"pm25" | "o3"> } = $props();
18
+
19
+ const chartManager = new DataChartManager();
20
+ let expanded = $state(false);
21
+ let calendarValue = $state<CalendarRange | undefined>({
22
+ start: parseAbsolute(chartManager.dateRange.start, "America/Los_Angeles"),
23
+ end: parseAbsolute(chartManager.dateRange.end, "America/Los_Angeles")
24
+ });
25
+ let dataRange = $state<CalendarRange | undefined>();
26
+ let calendarOpen = $state(false);
27
+ let dateRangeContainer: HTMLElement | undefined = $state();
28
+ let triggerRebuild: (() => void) | undefined = $state();
29
+
30
+ const dateRangeLabel = $derived(
31
+ format(parseISO(chartManager.dateRange.start), "MMM d") +
32
+ " – " +
33
+ format(parseISO(chartManager.dateRange.end), "MMM d, yyyy")
34
+ );
35
+
36
+ const noChartData = $derived(!chartManager.chartData.length);
37
+ const message = $derived(
38
+ chartManager.loading
39
+ ? "Loading Data"
40
+ : noChartData
41
+ ? "No Data Available For Selected Date Range"
42
+ : ""
43
+ );
44
+ const pollutantLabel = $derived(monitorsManager.pollutant === "pm25" ? "PM 2.5" : "Ozone");
45
+
46
+ $effect(() => {
47
+ if (monitor) loadChartData();
48
+ });
49
+
50
+ $effect(() => {
51
+ if (!calendarOpen) return;
52
+ function handleDocClick(e: MouseEvent) {
53
+ if (dateRangeContainer && !dateRangeContainer.contains(e.target as Node)) {
54
+ if (!calendarValue?.start || !calendarValue?.end) {
55
+ calendarValue = dataRange;
56
+ }
57
+ calendarOpen = false;
58
+ }
59
+ }
60
+ document.addEventListener("click", handleDocClick);
61
+ return () => document.removeEventListener("click", handleDocClick);
62
+ });
63
+
64
+ $effect(() => {
65
+ void chartManager.chartData; // re-run whenever chart data updates
66
+ triggerRebuild?.();
67
+ });
68
+
69
+ const chartAttachment: Attachment<HTMLElement> = (el) => {
70
+ let instance: uPlot | undefined;
71
+ let rafId: number;
72
+
73
+ const rebuild = () => {
74
+ if (!chartManager.chartData.length) return;
75
+ const { width, height } = el.getBoundingClientRect();
76
+ if (!width || !height) return;
77
+ const flatData = (chartManager.chartData.slice(1).flat() as (number | null)[]).filter(
78
+ (v): v is number => v !== null
79
+ );
80
+ if (!flatData.length) return;
81
+ instance?.destroy?.();
82
+ el.innerHTML = "";
83
+ const maxDiff = Math.max(...flatData) - Math.min(...flatData);
84
+ const opts = getChartConfig(monitor.type, maxDiff, width, height);
85
+ instance = new uPlot(opts, chartManager.chartData, el);
86
+ };
87
+
88
+ triggerRebuild = rebuild;
89
+
90
+ const ro = new ResizeObserver(() => {
91
+ cancelAnimationFrame(rafId);
92
+ rafId = requestAnimationFrame(rebuild);
93
+ });
94
+ ro.observe(el);
95
+
96
+ return () => {
97
+ triggerRebuild = undefined;
98
+ cancelAnimationFrame(rafId);
99
+ ro.disconnect();
100
+ instance?.destroy?.();
101
+ el.innerHTML = "";
102
+ };
103
+ };
104
+
105
+ async function loadChartData() {
106
+ chartManager.loading = true;
107
+ chartManager.chartData = await fetchChartData(monitor, chartManager.dateRange);
108
+ chartManager.loading = false;
109
+ }
110
+
111
+ function onUpdate() {
112
+ if (calendarValue?.start && calendarValue?.end) {
113
+ dataRange = calendarValue;
114
+ chartManager.dateRange = createDateRange(dataRange.start, dataRange.end);
115
+ calendarOpen = false;
116
+ loadChartData();
117
+ }
118
+ }
119
+
120
+ function downloadCSV() {
121
+ const url = getMonitorEntriesCSVUrl({
122
+ monitorId: monitor.id,
123
+ entryType: monitorsManager.pollutant ?? "pm25",
124
+ timestampGte: chartManager.dateRange.start,
125
+ timestampLte: chartManager.dateRange.end
126
+ });
127
+ window.open(url);
128
+ }
129
+
130
+ function downloadChart(e: MouseEvent) {
131
+ if (!e.shiftKey) return;
132
+ const canvas = (e.currentTarget as HTMLElement).querySelector(
133
+ "canvas"
134
+ ) as HTMLCanvasElement | null;
135
+ if (!canvas) return;
136
+ const link = document.createElement("a");
137
+ const monitorName = monitor.name.split(" ").join("-");
138
+ const start = format(parseISO(chartManager.dateRange.start), "dd.MMM.yyyy");
139
+ const end = format(parseISO(chartManager.dateRange.end), "dd.MMM.yyyy");
140
+ link.download = `${monitorName}_${start}-${end}.png`;
141
+ link.href = canvas.toDataURL();
142
+ link.click();
143
+ }
144
+
145
+ function myAction(node: HTMLElement, expanded: boolean) {
146
+ const parent = node.parentElement;
147
+ const sibling = node.nextElementSibling;
148
+ const mountpoint = document.getElementById("SJVAirMonitorMap");
149
+
150
+ function update(expanded: boolean) {
151
+ if (parent && mountpoint) {
152
+ if (expanded) {
153
+ // Start action logic (e.g., add event listeners)
154
+ mountpoint.moveBefore(node, mountpoint.firstElementChild);
155
+ } else {
156
+ // Stop action logic (e.g., remove event listeners)
157
+ parent.moveBefore(node, sibling);
158
+ }
159
+ }
160
+ }
161
+
162
+ update(expanded);
163
+
164
+ return {
165
+ update,
166
+ destroy() {
167
+ /* Clean up everything */
168
+ }
169
+ };
170
+ }
171
+ </script>
172
+
173
+ <div use:myAction={expanded} class="backdrop" class:expanded>
174
+ <div class="chart-panel" class:expanded>
175
+ <div class="flex items-center justify-between gap-2 p-1">
176
+ <div class={["relative", { "flex-1": expanded }]} bind:this={dateRangeContainer}>
177
+ <button
178
+ class="cursor-pointer rounded border border-gray-300 px-2 py-1 text-xs hover:bg-gray-50"
179
+ aria-expanded={calendarOpen}
180
+ onclick={() => (calendarOpen = !calendarOpen)}
181
+ >
182
+ {dateRangeLabel}
183
+ </button>
184
+ {#if calendarOpen}
185
+ <div
186
+ class="absolute top-full left-0 z-50 mt-1 rounded border border-gray-200 bg-white p-2 shadow-lg"
187
+ >
188
+ <RangeCalendar bind:value={calendarValue} maxDays={31} onValueChange={onUpdate} />
189
+ </div>
190
+ {/if}
191
+ </div>
192
+
193
+ <button
194
+ class={[
195
+ "cursor-pointer rounded border border-green-400 bg-green-500 px-2 py-1 text-xs font-semibold text-white hover:bg-green-600",
196
+ { "flex-none": expanded }
197
+ ]}
198
+ onclick={downloadCSV}
199
+ >
200
+ <!-- TODO: Get real icon -->
201
+ ⬇ Download
202
+ </button>
203
+
204
+ <div class={["text-right", { "flex-1": expanded }]}>
205
+ <button
206
+ class="cursor-pointer rounded p-0.5 hover:bg-gray-100"
207
+ onclick={() => (expanded = !expanded)}
208
+ title={expanded ? "Collapse" : "Expand Chart"}
209
+ >
210
+ {#if expanded}
211
+ <SquareX />
212
+ {:else}
213
+ <Maximize size={16} />
214
+ {/if}
215
+ </button>
216
+ </div>
217
+ </div>
218
+
219
+ <div class="chart-area relative">
220
+ {#if chartManager.loading || noChartData}
221
+ <div
222
+ class="absolute inset-0 flex flex-col items-center justify-center text-center text-2xl font-bold"
223
+ >
224
+ <!-- TODO: Get real icon -->
225
+ <span class:spin={chartManager.loading}>{chartManager.loading ? "↻" : "⚠"}</span>
226
+ <br />
227
+ {message}
228
+ </div>
229
+ {/if}
230
+ <h2
231
+ class="text-center text-xl font-bold"
232
+ class:invisible={chartManager.loading || noChartData}
233
+ >
234
+ {pollutantLabel} Readings
235
+ </h2>
236
+ <button
237
+ aria-label="Download"
238
+ class="chart-canvas"
239
+ class:invisible={chartManager.loading || noChartData}
240
+ onclick={downloadChart}
241
+ {@attach chartAttachment}
242
+ ></button>
243
+ </div>
244
+ </div>
245
+ </div>
246
+
247
+ <style>
248
+ .backdrop {
249
+ width: 100%;
250
+ }
251
+ .backdrop.expanded {
252
+ position: fixed;
253
+ inset: 0;
254
+ z-index: 9000;
255
+ background-color: rgba(0, 0, 0, 0.5);
256
+ backdrop-filter: blur(8px);
257
+ display: flex;
258
+ align-items: center;
259
+ justify-content: center;
260
+ }
261
+ .chart-panel {
262
+ position: relative;
263
+ display: flex;
264
+ flex-direction: column;
265
+ gap: 1rem;
266
+ padding: 0.5rem 0 1rem;
267
+ width: 100%;
268
+ }
269
+ .chart-panel.expanded {
270
+ width: 90%;
271
+ height: 68vh;
272
+ border-radius: 0.5rem;
273
+ background: white;
274
+ padding: 1rem;
275
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
276
+ }
277
+ .chart-area {
278
+ display: flex;
279
+ flex-direction: column;
280
+ height: 375px;
281
+ }
282
+ .chart-panel.expanded .chart-area {
283
+ flex: 1;
284
+ min-height: 0;
285
+ height: auto;
286
+ }
287
+ .chart-canvas {
288
+ flex: 1;
289
+ min-height: 0;
290
+ }
291
+ .spin {
292
+ display: inline-block;
293
+ animation: spinner 1s linear infinite;
294
+ }
295
+ @keyframes spinner {
296
+ from {
297
+ transform: rotate(0deg);
298
+ }
299
+ to {
300
+ transform: rotate(360deg);
301
+ }
302
+ }
303
+ </style>
@@ -0,0 +1,7 @@
1
+ import type { MonitorLatestType } from "@sjvair/sdk";
2
+ type $$ComponentProps = {
3
+ monitor: MonitorLatestType<"pm25" | "o3">;
4
+ };
5
+ declare const DataChart: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type DataChart = ReturnType<typeof DataChart>;
7
+ export default DataChart;
@@ -0,0 +1,6 @@
1
+ import type { DateValue } from "@internationalized/date";
2
+ export type DateRange = {
3
+ start: string;
4
+ end: string;
5
+ };
6
+ export declare function createDateRange(start?: DateValue, end?: DateValue): DateRange;
@@ -1,15 +1,16 @@
1
- import { endOfDay as e, isToday as t, startOfDay as n, subDays as r } from "date-fns";
2
- //#region src/lib/data-chart/DateRange.ts
3
- function i(i, a) {
4
- if (!i || !a) return {
5
- start: n(r(/* @__PURE__ */ new Date(), 1)).toISOString(),
6
- end: (/* @__PURE__ */ new Date()).toISOString()
7
- };
8
- let o = n(new Date(i.year, i.month - 1, i.day)), s = new Date(a.year, a.month - 1, a.day);
9
- return s = t(s) ? /* @__PURE__ */ new Date() : e(s), {
10
- start: o.toISOString(),
11
- end: s.toISOString()
12
- };
1
+ import { subDays, startOfDay, endOfDay, isToday } from "date-fns";
2
+ export function createDateRange(start, end) {
3
+ if (!start || !end) {
4
+ return {
5
+ start: startOfDay(subDays(new Date(), 1)).toISOString(),
6
+ end: new Date().toISOString()
7
+ };
8
+ }
9
+ const startDate = startOfDay(new Date(start.year, start.month - 1, start.day));
10
+ let endDate = new Date(end.year, end.month - 1, end.day);
11
+ endDate = isToday(endDate) ? new Date() : endOfDay(endDate);
12
+ return {
13
+ start: startDate.toISOString(),
14
+ end: endDate.toISOString()
15
+ };
13
16
  }
14
- //#endregion
15
- export { i as createDateRange };
@@ -0,0 +1,3 @@
1
+ import type uPlot from "uplot";
2
+ import type { MonitorType } from "@sjvair/sdk";
3
+ export declare function getChartConfig(sourceName: MonitorType, maxDiff: number, width: number, height: number): uPlot.Options;