@sybilion/uilib 1.2.24 → 1.3.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 (136) hide show
  1. package/dist/esm/components/ui/Chart/Chart.js +1 -0
  2. package/dist/esm/components/ui/Chart/components/BaseChartWrapper.js +7 -32
  3. package/dist/esm/components/ui/Chart/components/ChartEmptyState/ChartEmptyState.js +21 -0
  4. package/dist/esm/components/ui/Chart/components/ChartEmptyState/ChartEmptyState.styl.js +7 -0
  5. package/dist/esm/components/ui/Chart/tools/chartPlotGeometry.js +65 -0
  6. package/dist/esm/components/ui/ChartAreaInteractive/ChartAreaInteractive.helpers.js +37 -1
  7. package/dist/esm/components/ui/ChartAreaInteractive/ChartAreaInteractive.js +5 -2
  8. package/dist/esm/components/ui/ChartAreaInteractive/TimeRangeBrushLayer.js +205 -0
  9. package/dist/esm/components/ui/ChartAreaInteractive/TimeRangeBrushLayer.styl.js +7 -0
  10. package/dist/esm/components/ui/ChartAreaInteractive/TimeRangeBrushLayout.helpers.js +37 -0
  11. package/dist/esm/components/ui/ChartAreaInteractive/overlays/IntervalsOverlay/IntervalsOverlay.hooks.js +1 -0
  12. package/dist/esm/components/ui/ChartAreaInteractive/overlays/PinOverlay/PinOverlay.js +7 -60
  13. package/dist/esm/components/ui/ChartAreaInteractive/overlays/PinOverlay/PinOverlay.styl.js +2 -2
  14. package/dist/esm/components/ui/ChartAreaInteractive/overlays/ThresholdsOverlay/ThresholdsOverlay.hooks.js +1 -0
  15. package/dist/esm/components/ui/ChartAreaInteractive/overlays/useChartYRange.js +2 -4
  16. package/dist/esm/components/ui/Chat/ChatSheet/ChatSelector.js +1 -1
  17. package/dist/esm/components/ui/Chat/ChatSheet/ChatSelector.styl.js +1 -1
  18. package/dist/esm/components/ui/DropdownMenu/DropdownMenu.js +4 -4
  19. package/dist/esm/components/ui/TimeRangeControls/TimeRangeControls.js +7 -2
  20. package/dist/esm/components/ui/WorldMap/WorldMap.js +11 -0
  21. package/dist/esm/components/ui/WorldMap/WorldMap.styl.js +7 -0
  22. package/dist/esm/components/ui/WorldMap/map.svg.js +3 -0
  23. package/dist/esm/components/widgets/DriverCard/DriverCard.js +89 -0
  24. package/dist/esm/components/widgets/DriverCard/DriverCard.styl.js +7 -0
  25. package/dist/esm/components/widgets/DriverCard/DriverPerformanceChart.js +79 -0
  26. package/dist/esm/components/widgets/DriverCard/DriverPerformanceChart.styl.js +7 -0
  27. package/dist/esm/components/widgets/DriverCard/driverPerformanceChartData.js +50 -0
  28. package/dist/esm/components/widgets/DriverMap/DriverIcon/DriverIcon.constants.json.js +6 -0
  29. package/dist/esm/components/widgets/DriverMap/DriverIcon/DriverIcon.js +21 -0
  30. package/dist/esm/components/widgets/DriverMap/DriverIcon/DriverIcon.styl.js +7 -0
  31. package/dist/esm/components/widgets/DriverMap/DriverMap.helpers.js +107 -0
  32. package/dist/esm/components/widgets/DriverMap/DriverMap.js +129 -0
  33. package/dist/esm/components/widgets/DriverMap/DriverMap.styl.js +7 -0
  34. package/dist/esm/components/widgets/DriverMap/driverCategoryIcon.js +194 -0
  35. package/dist/esm/components/widgets/DriverMap/driverMapGeography.js +345 -0
  36. package/dist/esm/components/widgets/DriverMap/driverMapSelection.js +17 -0
  37. package/dist/esm/hooks/index.js +1 -0
  38. package/dist/esm/hooks/useEvent.js +0 -2
  39. package/dist/esm/index.js +7 -0
  40. package/dist/esm/types/src/components/ui/Chart/Chart.d.ts +1 -0
  41. package/dist/esm/types/src/components/ui/Chart/components/BaseChartWrapper.d.ts +2 -1
  42. package/dist/esm/types/src/components/ui/Chart/components/ChartEmptyState/ChartEmptyState.d.ts +14 -0
  43. package/dist/esm/types/src/components/ui/Chart/tools/chartPlotGeometry.d.ts +30 -0
  44. package/dist/esm/types/src/components/ui/ChartAreaInteractive/ChartAreaInteractive.d.ts +1 -1
  45. package/dist/esm/types/src/components/ui/ChartAreaInteractive/ChartAreaInteractive.helpers.d.ts +11 -2
  46. package/dist/esm/types/src/components/ui/ChartAreaInteractive/ChartAreaInteractive.types.d.ts +2 -2
  47. package/dist/esm/types/src/components/ui/ChartAreaInteractive/TimeRangeBrushLayer.d.ts +15 -0
  48. package/dist/esm/types/src/components/ui/ChartAreaInteractive/TimeRangeBrushLayout.helpers.d.ts +14 -0
  49. package/dist/esm/types/src/components/ui/ChartAreaInteractive/overlays/PinOverlay/PinOverlay.d.ts +1 -1
  50. package/dist/esm/types/src/components/ui/DropdownMenu/DropdownMenu.d.ts +2 -2
  51. package/dist/esm/types/src/components/ui/Page/PageColumns/PageColumns.d.ts +1 -1
  52. package/dist/esm/types/src/components/ui/TimeRangeControls/TimeRangeControls.d.ts +5 -7
  53. package/dist/esm/types/src/components/ui/WorldMap/WorldMap.d.ts +4 -0
  54. package/dist/esm/types/src/components/ui/WorldMap/index.d.ts +2 -0
  55. package/dist/esm/types/src/components/widgets/DriverCard/DriverCard.d.ts +9 -0
  56. package/dist/esm/types/src/components/widgets/DriverCard/DriverPerformanceChart.d.ts +5 -0
  57. package/dist/esm/types/src/components/widgets/DriverCard/driverPerformanceChartData.d.ts +7 -0
  58. package/dist/esm/types/src/components/widgets/DriverCard/index.d.ts +1 -0
  59. package/dist/esm/types/src/components/widgets/DriverMap/DriverIcon/DriverIcon.d.ts +17 -0
  60. package/dist/esm/types/src/components/widgets/DriverMap/DriverMap.d.ts +8 -0
  61. package/dist/esm/types/src/components/widgets/DriverMap/DriverMap.helpers.d.ts +21 -0
  62. package/dist/esm/types/src/components/widgets/DriverMap/driverCategoryIcon.d.ts +1 -0
  63. package/dist/esm/types/src/components/widgets/DriverMap/driverMapGeography.d.ts +80 -0
  64. package/dist/esm/types/src/components/widgets/DriverMap/driverMapSelection.d.ts +3 -0
  65. package/dist/esm/types/src/components/widgets/DriverMap/index.d.ts +6 -0
  66. package/dist/esm/types/src/docs/pages/DriverMapPage.d.ts +1 -0
  67. package/dist/esm/types/src/docs/pages/PageColumnsPage.d.ts +1 -0
  68. package/dist/esm/types/src/docs/pages/WorldMapPage.d.ts +1 -0
  69. package/dist/esm/types/src/docs/registry.d.ts +1 -1
  70. package/dist/esm/types/src/hooks/index.d.ts +1 -0
  71. package/dist/esm/types/src/index.d.ts +3 -0
  72. package/package.json +1 -1
  73. package/src/components/ui/Chart/Chart.tsx +5 -0
  74. package/src/components/ui/Chart/components/BaseChartWrapper.tsx +8 -41
  75. package/src/components/ui/Chart/components/ChartEmptyState/ChartEmptyState.styl +60 -0
  76. package/src/components/ui/Chart/components/ChartEmptyState/ChartEmptyState.styl.d.ts +15 -0
  77. package/src/components/ui/Chart/components/ChartEmptyState/ChartEmptyState.tsx +66 -0
  78. package/src/components/ui/Chart/tools/chartPlotGeometry.ts +89 -0
  79. package/src/components/ui/ChartAreaInteractive/ChartAreaInteractive.helpers.ts +44 -2
  80. package/src/components/ui/ChartAreaInteractive/ChartAreaInteractive.tsx +14 -1
  81. package/src/components/ui/ChartAreaInteractive/ChartAreaInteractive.types.ts +2 -3
  82. package/src/components/ui/ChartAreaInteractive/TimeRangeBrushLayer.styl +21 -0
  83. package/src/components/ui/ChartAreaInteractive/TimeRangeBrushLayer.styl.d.ts +9 -0
  84. package/src/components/ui/ChartAreaInteractive/TimeRangeBrushLayer.tsx +285 -0
  85. package/src/components/ui/ChartAreaInteractive/TimeRangeBrushLayout.helpers.ts +55 -0
  86. package/src/components/ui/ChartAreaInteractive/overlays/IntervalsOverlay/IntervalsOverlay.hooks.ts +1 -0
  87. package/src/components/ui/ChartAreaInteractive/overlays/PinOverlay/PinOverlay.styl +2 -7
  88. package/src/components/ui/ChartAreaInteractive/overlays/PinOverlay/PinOverlay.styl.d.ts +0 -1
  89. package/src/components/ui/ChartAreaInteractive/overlays/PinOverlay/PinOverlay.tsx +7 -71
  90. package/src/components/ui/ChartAreaInteractive/overlays/ThresholdsOverlay/ThresholdsOverlay.hooks.ts +1 -0
  91. package/src/components/ui/ChartAreaInteractive/overlays/useChartYRange.ts +2 -3
  92. package/src/components/ui/Chat/ChatSheet/ChatSelector.styl +3 -1
  93. package/src/components/ui/Chat/ChatSheet/ChatSelector.tsx +1 -1
  94. package/src/components/ui/DropdownMenu/DropdownMenu.tsx +4 -0
  95. package/src/components/ui/Page/PageColumns/PageColumns.tsx +1 -1
  96. package/src/components/ui/TimeRangeControls/TimeRangeControls.tsx +16 -17
  97. package/src/components/ui/WorldMap/WorldMap.styl +11 -0
  98. package/src/components/ui/WorldMap/WorldMap.styl.d.ts +7 -0
  99. package/src/components/ui/WorldMap/WorldMap.tsx +22 -0
  100. package/src/components/ui/WorldMap/index.ts +2 -0
  101. package/src/components/ui/WorldMap/map.svg +4337 -0
  102. package/src/components/ui/WorldMap/mapAspect.mixin.styl +3 -0
  103. package/src/components/ui/WorldMap/mapAspect.mixin.styl.d.ts +2 -0
  104. package/src/components/widgets/DriverCard/DriverCard.styl +169 -0
  105. package/src/components/widgets/DriverCard/DriverCard.styl.d.ts +40 -0
  106. package/src/components/widgets/DriverCard/DriverCard.tsx +219 -0
  107. package/src/components/widgets/DriverCard/DriverPerformanceChart.styl +43 -0
  108. package/src/components/widgets/DriverCard/DriverPerformanceChart.styl.d.ts +13 -0
  109. package/src/components/widgets/DriverCard/DriverPerformanceChart.tsx +150 -0
  110. package/src/components/widgets/DriverCard/driverPerformanceChartData.ts +64 -0
  111. package/src/components/widgets/DriverCard/index.ts +1 -0
  112. package/src/components/widgets/DriverMap/DriverIcon/DriverIcon.constants.json +3 -0
  113. package/src/components/widgets/DriverMap/DriverIcon/DriverIcon.styl +125 -0
  114. package/src/components/widgets/DriverMap/DriverIcon/DriverIcon.styl.d.ts +22 -0
  115. package/src/components/widgets/DriverMap/DriverIcon/DriverIcon.tsx +79 -0
  116. package/src/components/widgets/DriverMap/DriverMap.helpers.ts +164 -0
  117. package/src/components/widgets/DriverMap/DriverMap.styl +50 -0
  118. package/src/components/widgets/DriverMap/DriverMap.styl.d.ts +12 -0
  119. package/src/components/widgets/DriverMap/DriverMap.tsx +212 -0
  120. package/src/components/widgets/DriverMap/driverCategoryIcon.tsx +277 -0
  121. package/src/components/widgets/DriverMap/driverMapGeography.ts +478 -0
  122. package/src/components/widgets/DriverMap/driverMapSelection.ts +23 -0
  123. package/src/components/widgets/DriverMap/index.ts +16 -0
  124. package/src/docs/config/webpack.config.js +25 -9
  125. package/src/docs/pages/ChartAreaInteractivePage.tsx +2 -3
  126. package/src/docs/pages/DriverMapPage.tsx +268 -0
  127. package/src/docs/pages/PageColumnsPage.tsx +92 -0
  128. package/src/docs/pages/TimeRangeControlsPage.tsx +2 -3
  129. package/src/docs/pages/TooltipPage.tsx +14 -10
  130. package/src/docs/pages/WorldMapPage.styl +14 -0
  131. package/src/docs/pages/WorldMapPage.styl.d.ts +8 -0
  132. package/src/docs/pages/WorldMapPage.tsx +26 -0
  133. package/src/docs/registry.ts +18 -5
  134. package/src/hooks/index.ts +1 -0
  135. package/src/hooks/useEvent.ts +0 -2
  136. package/src/index.ts +3 -0
@@ -6,23 +6,19 @@ import 'recharts';
6
6
  import '../../../Chart/Chart.context.js';
7
7
  import '../../../Chart/Chart.styl.js';
8
8
  import { useDebounceCallback } from '../../../../../hooks/useDebounceCallback.js';
9
- import useElemDrag from '../../../../../hooks/useDragElem.js';
10
9
  import { ChevronsLeftRight } from 'lucide-react';
11
10
  import S from '../../ChartAreaInteractive.styl.js';
12
11
  import { useChartYRange } from '../useChartYRange.js';
13
12
  import S$1 from './PinOverlay.styl.js';
14
13
 
15
- function PinOverlay({ baseChartProps, pinMonth, onPinMonthChange, onPreviewMonthChange, className, }) {
14
+ function PinOverlay({ baseChartProps, pinMonth, onPinMonthChange, onPreviewMonthChange: _onPreviewMonthChange, className, }) {
16
15
  const { chartData } = baseChartProps;
17
16
  const chartRef = useRef(null);
18
17
  const pinRef = useRef(null);
19
18
  const pinPlaceholderRef = useRef(null);
20
19
  const pinContainerRef = useRef(null);
21
- const [isDraggingPin, setIsDraggingPin] = useState(false);
22
- const [isPinAnimating, setIsPinAnimating] = useState(true);
23
20
  const [isPinHovered, setIsPinHovered] = useState(false);
24
21
  const pinPosRef = useRef(0);
25
- const containerRectRef = useRef(null);
26
22
  const currPinMonthRef = useRef(pinMonth);
27
23
  const debouncedOnPinMonthChange = useDebounceCallback((...args) => onPinMonthChange?.(args[0]), 500, [onPinMonthChange]);
28
24
  const { yMin, yMax } = useChartYRange({
@@ -38,7 +34,6 @@ function PinOverlay({ baseChartProps, pinMonth, onPinMonthChange, onPreviewMonth
38
34
  pinPlaceholderRef.current.style.left = `${position}%`;
39
35
  }
40
36
  };
41
- // Get full month and year for pin position to send to parent component
42
37
  const getPinMonthAndYear = (position) => {
43
38
  if (!chartData.length)
44
39
  return null;
@@ -54,18 +49,15 @@ function PinOverlay({ baseChartProps, pinMonth, onPinMonthChange, onPreviewMonth
54
49
  return `${month} ${year}`;
55
50
  }
56
51
  };
57
- // Handle chart click to move pin to specific position
58
52
  const snapPinToPosition = (eventX, needMonthUpdate = true, immediateMonthUpdate = false) => {
59
53
  if (!pinContainerRef.current || !chartData.length)
60
54
  return;
61
55
  const pinContainerRect = pinContainerRef.current.getBoundingClientRect();
62
56
  const effectiveLeft = pinContainerRect.left;
63
57
  const effectiveWidth = pinContainerRect.width;
64
- // Calculate relative position within plotted area
65
58
  const relativeX = eventX - effectiveLeft;
66
59
  const rawPercentage = effectiveWidth > 0 ? (relativeX / effectiveWidth) * 100 : 0;
67
60
  const percentage = Math.max(0, Math.min(100, isNaN(rawPercentage) ? 0 : rawPercentage));
68
- // Snap to nearest data point
69
61
  const totalPoints = chartData.length;
70
62
  if (totalPoints > 1) {
71
63
  const nearestIndex = Math.round((percentage / 100) * (totalPoints - 1));
@@ -73,13 +65,11 @@ function PinOverlay({ baseChartProps, pinMonth, onPinMonthChange, onPreviewMonth
73
65
  const snappedPercentage = (clampedIndex / (totalPoints - 1)) * 100;
74
66
  setPinPosition(isNaN(snappedPercentage) ? 0 : snappedPercentage);
75
67
  if (needMonthUpdate) {
76
- // Update news for all months (historical and forecast)
77
68
  const monthAndYear = getPinMonthAndYear();
78
69
  if (monthAndYear) {
79
70
  const isNewMonth = monthAndYear !== currPinMonthRef.current;
80
71
  if (isNewMonth)
81
72
  currPinMonthRef.current = monthAndYear;
82
- // When immediate (e.g. dragEnd), always notify parent so showFutureOutlook is correct
83
73
  if (immediateMonthUpdate) {
84
74
  onPinMonthChange?.(monthAndYear);
85
75
  }
@@ -90,11 +80,9 @@ function PinOverlay({ baseChartProps, pinMonth, onPinMonthChange, onPreviewMonth
90
80
  }
91
81
  }
92
82
  };
93
- // Update pin position when pinMonth prop changes
94
83
  useEffect(() => {
95
84
  if (!pinMonth || !chartData.length)
96
85
  return;
97
- // Find the data point index for the given month
98
86
  const dataPointIndex = chartData.findIndex(point => {
99
87
  const date = new Date(point.date);
100
88
  const month = date.toLocaleDateString('en-US', { month: 'short' });
@@ -109,57 +97,16 @@ function PinOverlay({ baseChartProps, pinMonth, onPinMonthChange, onPreviewMonth
109
97
  currPinMonthRef.current = pinMonth;
110
98
  }
111
99
  }, [pinMonth, chartData]);
112
- useElemDrag({
113
- elem: [chartRef],
114
- onDragStart: () => {
115
- setIsDraggingPin(true);
116
- containerRectRef.current =
117
- pinContainerRef.current?.getBoundingClientRect() || null;
118
- },
119
- onDrag: (delta) => {
120
- if (pinRef.current) {
121
- const containerRect = containerRectRef.current;
122
- if (!containerRect)
123
- return;
124
- const pinCurrentLeft = (pinPosRef.current / 100) * containerRect.width;
125
- const leftLimit = -pinCurrentLeft;
126
- const rightLimit = containerRect.width - pinCurrentLeft;
127
- const clampedDeltaX = Math.max(leftLimit, Math.min(rightLimit, delta.x));
128
- setIsPinAnimating(false);
129
- pinRef.current.style.transform = `translateX(${clampedDeltaX}px)`;
130
- // Calculate preview month based on current drag position
131
- if (onPreviewMonthChange && chartData.length > 0) {
132
- const newPositionPixels = pinCurrentLeft + clampedDeltaX;
133
- const newPercentage = (newPositionPixels / containerRect.width) * 100;
134
- const clampedPercentage = Math.max(0, Math.min(100, newPercentage));
135
- const previewMonth = getPinMonthAndYear(clampedPercentage);
136
- if (previewMonth) {
137
- onPreviewMonthChange(previewMonth);
138
- }
139
- }
140
- }
141
- },
142
- onDragEnd: (e) => {
143
- setIsDraggingPin(false);
144
- setTimeout(() => setIsPinAnimating(true), 200);
145
- if (pinRef.current)
146
- pinRef.current.style.transform = '';
147
- // Snap first so onPinMonthChange runs before we clear preview (avoids showFutureOutlook fallback)
148
- snapPinToPosition(e.clientX, true, true);
149
- if (onPreviewMonthChange) {
150
- onPreviewMonthChange(undefined);
151
- }
152
- },
153
- });
154
- const onPointerDown = (e) => {
155
- if (e.target.tagName !== 'svg')
100
+ const onChartClick = (e) => {
101
+ if (e.button !== 0)
102
+ return;
103
+ const target = e.target;
104
+ if (!target.closest?.('svg'))
156
105
  return;
157
106
  snapPinToPosition(e.clientX, true, false);
158
107
  };
159
108
  const overlay = (jsxs(Fragment, { children: [jsx("div", { className: cn(S.overlay, S$1.pinContainer), ref: pinContainerRef, children: jsx("div", { className: S$1.pinLineBase, style: { left: `${pinPosRef.current}%` }, ref: pinRef, children: jsx("div", { className: S$1.pinButton, "aria-label": "News pin", title: `Current month: ${getPinMonthAndYear() || 'Loading...'}`, children: jsx(ChevronsLeftRight, { className: S$1.pinIcon, "aria-hidden": "true" }) }) }) }), jsx("div", { className: S$1.pinPlaceholder, style: { left: `${pinPosRef.current}%` }, ref: pinPlaceholderRef, onPointerEnter: () => setIsPinHovered(true), onPointerLeave: () => setIsPinHovered(false) })] }));
160
- return (jsx("div", { className: cn(className, S$1.root, isDraggingPin && S$1.pinDragging, isPinAnimating && S$1.pinAnimating, isPinHovered && S$1.pinHovered), onPointerDown: onPointerDown,
161
- // onClick={e => snapPinToPosition(e.clientX)}
162
- ref: chartRef, children: jsx(BaseChartWrapper, { ...baseChartProps, yMin: yMin, yMax: yMax, autoScaleYAxis: false, overlayElements: overlay }) }));
109
+ return (jsx("div", { className: cn(className, S$1.root, S$1.pinAnimating, isPinHovered && S$1.pinHovered), onClick: onChartClick, ref: chartRef, children: jsx(BaseChartWrapper, { ...baseChartProps, yMin: yMin, yMax: yMax, autoScaleYAxis: false, overlayElements: overlay }) }));
163
110
  }
164
111
 
165
112
  export { PinOverlay };
@@ -1,7 +1,7 @@
1
1
  import styleInject from 'style-inject';
2
2
 
3
- var css_248z = ".PinOverlay_root__RUZxO{touch-action:pan-y}.PinOverlay_pinContainer__6sc1J{height:calc(var(--chart-height) - 70px);inset:0;margin:var(--p-5) var(--p-8) var(--p-24) var(--p-12);pointer-events:none;position:absolute;touch-action:pan-y;transition:transform .2s ease-out,z-index 0ms;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:2}.PinOverlay_pinHovered__cGPjN .PinOverlay_pinContainer__6sc1J{z-index:10}.PinOverlay_pinLineBase__0BWsD{height:100%;pointer-events:none;position:absolute;width:3px}.PinOverlay_pinLineBase__0BWsD:before{border-radius:50%;box-shadow:0 4px 6px -1px var(--shadow-color);content:\"\";height:36px;left:-16px;position:absolute;top:-8px;width:36px;z-index:-1}.PinOverlay_pinLineBase__0BWsD:after{background-color:var(--background);border-radius:12px;bottom:0;content:\"\";left:0;position:absolute;top:0;transform:translate3d(.5px,0,0);transition:background-color .3s ease-out;width:100%;z-index:1}.PinOverlay_pinDragging__gu3xp .PinOverlay_pinLineBase__0BWsD:after{background-color:var(--background-alpha-700)}.PinOverlay_pinAnimating__5XMJG .PinOverlay_pinLineBase__0BWsD{transition:left .3s ease-out}.PinOverlay_pinButton__cnV1K{position:absolute;--offset:-8px;align-items:center;background-color:var(--background);border-radius:9999px;cursor:grab;display:flex;justify-content:center;left:-8px;left:var(--offset);margin-left:-8px;margin-left:var(--offset);padding:10px;pointer-events:auto;top:-18px;touch-action:none;transition:transform .2s ease-out;-webkit-user-select:none;-moz-user-select:none;user-select:none}.PinOverlay_pinDragging__gu3xp .PinOverlay_pinButton__cnV1K{transition:none}.PinOverlay_pinHovered__cGPjN .PinOverlay_pinButton__cnV1K{transform:scale(1.1)}.PinOverlay_pinButton__cnV1K:active{cursor:grabbing}.PinOverlay_pinIcon__s7Ze0{color:var(--foreground);height:16px;width:16px}.PinOverlay_pinPlaceholder__JhKcQ{cursor:grab;height:72px;margin-left:-40px;margin-top:-40px;pointer-events:auto;position:absolute;top:var(--p-5);touch-action:none;width:72px;z-index:20}.PinOverlay_pinAnimating__5XMJG .PinOverlay_pinPlaceholder__JhKcQ{transition:left .3s ease-out}.PinOverlay_pinPlaceholder__JhKcQ:active{cursor:grabbing}";
4
- var S = {"root":"PinOverlay_root__RUZxO","pinContainer":"PinOverlay_pinContainer__6sc1J","pinHovered":"PinOverlay_pinHovered__cGPjN","pinLineBase":"PinOverlay_pinLineBase__0BWsD","pinDragging":"PinOverlay_pinDragging__gu3xp","pinAnimating":"PinOverlay_pinAnimating__5XMJG","pinButton":"PinOverlay_pinButton__cnV1K","pinIcon":"PinOverlay_pinIcon__s7Ze0","pinPlaceholder":"PinOverlay_pinPlaceholder__JhKcQ"};
3
+ var css_248z = ".PinOverlay_root__RUZxO{touch-action:pan-y}.PinOverlay_pinContainer__6sc1J{height:calc(var(--chart-height) - 70px);inset:0;margin:var(--p-5) var(--p-8) var(--p-24) var(--p-12);pointer-events:none;position:absolute;touch-action:pan-y;transition:transform .2s ease-out,z-index 0ms;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:2}.PinOverlay_pinHovered__cGPjN .PinOverlay_pinContainer__6sc1J{z-index:10}.PinOverlay_pinLineBase__0BWsD{height:100%;pointer-events:none;position:absolute;width:3px}.PinOverlay_pinLineBase__0BWsD:before{border-radius:50%;box-shadow:0 4px 6px -1px var(--shadow-color);content:\"\";height:36px;left:-16px;position:absolute;top:-8px;width:36px;z-index:-1}.PinOverlay_pinLineBase__0BWsD:after{background-color:var(--background);border-radius:12px;bottom:0;content:\"\";left:0;position:absolute;top:0;transform:translate3d(.5px,0,0);transition:background-color .3s ease-out;width:100%;z-index:1}.PinOverlay_pinAnimating__5XMJG .PinOverlay_pinLineBase__0BWsD{transition:left .3s ease-out}.PinOverlay_pinButton__cnV1K{position:absolute;--offset:-8px;align-items:center;background-color:var(--background);border-radius:9999px;cursor:pointer;display:flex;justify-content:center;left:-8px;left:var(--offset);margin-left:-8px;margin-left:var(--offset);padding:10px;pointer-events:auto;top:-18px;touch-action:none;transition:transform .2s ease-out;-webkit-user-select:none;-moz-user-select:none;user-select:none}.PinOverlay_pinHovered__cGPjN .PinOverlay_pinButton__cnV1K{transform:scale(1.1)}.PinOverlay_pinButton__cnV1K:active{cursor:grabbing}.PinOverlay_pinIcon__s7Ze0{color:var(--foreground);height:16px;width:16px}.PinOverlay_pinPlaceholder__JhKcQ{cursor:pointer;height:72px;margin-left:-40px;margin-top:-40px;pointer-events:auto;position:absolute;top:var(--p-5);touch-action:none;width:72px;z-index:20}.PinOverlay_pinAnimating__5XMJG .PinOverlay_pinPlaceholder__JhKcQ{transition:left .3s ease-out}.PinOverlay_pinPlaceholder__JhKcQ:active{cursor:grabbing}";
4
+ var S = {"root":"PinOverlay_root__RUZxO","pinContainer":"PinOverlay_pinContainer__6sc1J","pinHovered":"PinOverlay_pinHovered__cGPjN","pinLineBase":"PinOverlay_pinLineBase__0BWsD","pinAnimating":"PinOverlay_pinAnimating__5XMJG","pinButton":"PinOverlay_pinButton__cnV1K","pinIcon":"PinOverlay_pinIcon__s7Ze0","pinPlaceholder":"PinOverlay_pinPlaceholder__JhKcQ"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { S as default };
@@ -70,6 +70,7 @@ function useThresholdButton({ lineRef, overlayContainerRef, initialValue, minVal
70
70
  onValueChangeThrottled(clampedValue);
71
71
  }, [clientYToValue, valueToPercent, minValue, maxValue]);
72
72
  const handleDragStart = useCallback((e) => {
73
+ e.stopPropagation();
73
74
  initialValueRef.current = initialValue;
74
75
  startYRef.current = e.clientY;
75
76
  setIsDragging(true);
@@ -15,11 +15,9 @@ function useChartYRange({ baseChartProps, chartData, disableRescaleWhenQuantileC
15
15
  Object.entries(point).forEach(([key, value]) => {
16
16
  if (key === 'date')
17
17
  return;
18
- // When selectedForecastId is provided, scale only from selected forecast + its quantile band
19
- // (exclude historical, other forecasts, and other forecasts' quantile values)
18
+ // When selectedForecastId is provided, scale from historical + selected forecast + its
19
+ // quantile band (exclude other forecasts and their quantile values only).
20
20
  if (forecastId !== undefined) {
21
- if (key === 'historical')
22
- return;
23
21
  if (key.startsWith('forecast_') && key !== `forecast_${forecastId}`)
24
22
  return;
25
23
  // Exclude q{quantile}_{otherAnalysisId} - only include selected forecast's quantiles
@@ -32,7 +32,7 @@ function ChatSelector({ id, className, onChatDeleted, }) {
32
32
  return (firstMessage.text.slice(0, 30) +
33
33
  (firstMessage.text.length > 30 ? '...' : ''));
34
34
  }
35
- return `Chat ${chat.session_id}`;
35
+ return 'New chat';
36
36
  };
37
37
  return (jsxs("div", { className: S.wrapper, children: [jsx("div", { className: S.selectGrow, children: jsxs(Select, { variant: "clear", value: currentChatId?.toString() ?? '', onValueChange: handleValueChange, children: [jsx(SelectTrigger, { size: "sm", className: className ? cn(S.selectTrigger, className) : S.selectTrigger, children: jsx(SelectValue, { placeholder: "Select chat" }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "new", children: "+ New Chat" }), chats.map(chat => (jsx(SelectItem, { value: chat.session_id.toString(), selected: chat.session_id === currentChatId, children: getChatDisplayName(chat) }, chat.session_id)))] })] }) }), jsx(Button, { type: "button", variant: "ghost", size: "sm", className: S.deleteBtn, "aria-label": "Delete chat", disabled: !currentChatId || chats.length === 0, onClick: handleDeleteChat, children: jsx(Trash2Icon, { size: 16 }) })] }));
38
38
  }
@@ -1,6 +1,6 @@
1
1
  import styleInject from 'style-inject';
2
2
 
3
- var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.ChatSelector_wrapper__8Z4wN{align-items:center;display:flex;gap:var(--p-2);min-width:200px;z-index:1000}.ChatSelector_selectGrow__bGR0A{flex:1;min-width:0}.ChatSelector_selectTrigger__DASfc{width:100%}.ChatSelector_deleteBtn__oJ-9b{border-radius:50px;flex-shrink:0;opacity:.3}.ChatSelector_wrapper__8Z4wN:hover .ChatSelector_deleteBtn__oJ-9b{opacity:1}";
3
+ var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.ChatSelector_wrapper__8Z4wN{align-items:center;display:flex;gap:var(--p-2);min-width:200px;z-index:1000}.ChatSelector_selectGrow__bGR0A{flex:1;min-width:0}.ChatSelector_selectTrigger__DASfc{width:100%}.ChatSelector_deleteBtn__oJ-9b{border-radius:50px;flex-shrink:0;opacity:0;pointer-events:none}.ChatSelector_wrapper__8Z4wN:hover .ChatSelector_deleteBtn__oJ-9b{opacity:1;pointer-events:auto}";
4
4
  var S = {"wrapper":"ChatSelector_wrapper__8Z4wN","selectGrow":"ChatSelector_selectGrow__bGR0A","selectTrigger":"ChatSelector_selectTrigger__DASfc","deleteBtn":"ChatSelector_deleteBtn__oJ-9b"};
5
5
  styleInject(css_248z);
6
6
 
@@ -13,8 +13,8 @@ function DropdownMenuPortal({ ...props }) {
13
13
  function DropdownMenuTrigger({ ...props }) {
14
14
  return (jsx(DropdownMenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props }));
15
15
  }
16
- function DropdownMenuContent({ className, sideOffset = 4, elevation = 'sm', ...props }) {
17
- return (jsx(DropdownMenuPrimitive.Portal, { children: jsx(DropdownMenuPrimitive.Content, { "data-slot": "dropdown-menu-content", sideOffset: sideOffset, className: cn(S.content, S[`elevation-${elevation}`], className), ...props }) }));
16
+ function DropdownMenuContent({ className, sideOffset = 4, collisionPadding = 8, elevation = 'sm', ...props }) {
17
+ return (jsx(DropdownMenuPrimitive.Portal, { children: jsx(DropdownMenuPrimitive.Content, { "data-slot": "dropdown-menu-content", sideOffset: sideOffset, collisionPadding: collisionPadding, className: cn(S.content, S[`elevation-${elevation}`], className), ...props }) }));
18
18
  }
19
19
  function DropdownMenuGroup({ ...props }) {
20
20
  return (jsx(DropdownMenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props }));
@@ -46,8 +46,8 @@ function DropdownMenuSub({ ...props }) {
46
46
  function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
47
47
  return (jsxs(DropdownMenuPrimitive.SubTrigger, { "data-slot": "dropdown-menu-sub-trigger", "data-inset": inset, className: cn(S.subTrigger, className), ...props, children: [children, jsx(CaretRight, { className: "ml-auto size-4" })] }));
48
48
  }
49
- function DropdownMenuSubContent({ className, ...props }) {
50
- return (jsx(DropdownMenuPrimitive.SubContent, { "data-slot": "dropdown-menu-sub-content", className: cn(S.subContent, className), ...props }));
49
+ function DropdownMenuSubContent({ className, collisionPadding = 8, ...props }) {
50
+ return (jsx(DropdownMenuPrimitive.SubContent, { "data-slot": "dropdown-menu-sub-content", collisionPadding: collisionPadding, className: cn(S.subContent, className), ...props }));
51
51
  }
52
52
 
53
53
  export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger };
@@ -5,9 +5,14 @@ import { ToggleGroup, ToggleGroupItem } from '../ToggleGroup/ToggleGroup.js';
5
5
  import { TIME_RANGES } from './TimeRangeControls.constants.js';
6
6
  import S from './TimeRangeControls.styl.js';
7
7
 
8
- const TimeRangeControls = memo(({ timeRange, onTimeRangeChange, loading, }) => (jsx("div", { className: S.timeRangeContainer, children: jsx(ToggleGroup, { type: "single", value: timeRange, onValueChange: onTimeRangeChange, variant: "outline", disabled: loading, className: S.timeRangeToggleGroup, children: TIME_RANGES.map(range => (jsx(ToggleGroupItem, { value: range, className: S.timeRangeToggleItem, children: range }, range))) }) })));
8
+ function toggleValueForTimeRange(timeRange) {
9
+ return TIME_RANGES.includes(timeRange)
10
+ ? timeRange
11
+ : '';
12
+ }
13
+ const TimeRangeControls = memo(({ timeRange, onTimeRangeChange, loading }) => (jsx("div", { className: S.timeRangeContainer, children: jsx(ToggleGroup, { type: "single", value: toggleValueForTimeRange(timeRange), onValueChange: onTimeRangeChange, variant: "outline", disabled: loading, className: S.timeRangeToggleGroup, children: TIME_RANGES.map(range => (jsx(ToggleGroupItem, { value: range, className: S.timeRangeToggleItem, children: range }, range))) }) })));
9
14
  TimeRangeControls.displayName = 'TimeRangeControls';
10
- const TimeRangeSelect = memo(({ timeRange, onTimeRangeChange, loading, }) => (jsxs(Select, { value: timeRange, onValueChange: onTimeRangeChange, disabled: loading, children: [jsx(SelectTrigger, { className: S.timeRangeSelectTrigger, size: "sm", "aria-label": "Select a value", children: jsx(SelectValue, { placeholder: "1 year" }) }), jsx(SelectContent, { className: S.timeRangeSelectContent, children: TIME_RANGES.map(range => (jsx(SelectItem, { value: range, className: S.timeRangeSelectItem, children: range }, range))) })] })));
15
+ const TimeRangeSelect = memo(({ timeRange, onTimeRangeChange, loading, }) => (jsxs(Select, { value: toggleValueForTimeRange(timeRange) || undefined, onValueChange: onTimeRangeChange, disabled: loading, children: [jsx(SelectTrigger, { className: S.timeRangeSelectTrigger, size: "sm", "aria-label": "Select a value", children: jsx(SelectValue, { placeholder: "1 year" }) }), jsx(SelectContent, { className: S.timeRangeSelectContent, children: TIME_RANGES.map(range => (jsx(SelectItem, { value: range, className: S.timeRangeSelectItem, children: range }, range))) })] })));
11
16
  TimeRangeSelect.displayName = 'TimeRangeSelect';
12
17
 
13
18
  export { TimeRangeControls, TimeRangeSelect };
@@ -0,0 +1,11 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import cn from 'classnames';
3
+ import S from './WorldMap.styl.js';
4
+ import mapBgUrl from './map.svg.js';
5
+
6
+ function WorldMap({ className }) {
7
+ const src = mapBgUrl;
8
+ return (jsx("img", { alt: "", className: cn(S.worldMap, className), decoding: "async", draggable: false, src: src }));
9
+ }
10
+
11
+ export { WorldMap };
@@ -0,0 +1,7 @@
1
+ import styleInject from 'style-inject';
2
+
3
+ var css_248z = ".WorldMap_worldMap__XTiex{aspect-ratio:623.2/341.276;display:block;height:100%;max-width:100%;-o-object-fit:contain;object-fit:contain;-o-object-position:center;object-position:center;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}";
4
+ var S = {"worldMap":"WorldMap_worldMap__XTiex"};
5
+ styleInject(css_248z);
6
+
7
+ export { S as default };