@terraware/web-components 5.0.27 → 5.1.1-rc.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 (311) hide show
  1. package/components/AntSwitch/index.js +19 -22
  2. package/components/Autocomplete/Autocomplete.js +106 -130
  3. package/components/Badge/index.js +28 -29
  4. package/components/BusySpinner/index.js +40 -45
  5. package/components/Button/Button.js +41 -47
  6. package/components/Checkbox.js +64 -63
  7. package/components/Confirm/index.js +74 -83
  8. package/components/DatePicker/DatePicker.js +138 -141
  9. package/components/DialogBox/DialogBox.js +111 -118
  10. package/components/Divisor.js +18 -18
  11. package/components/Dropdown.js +66 -94
  12. package/components/EditableTable/index.js +211 -271
  13. package/components/ErrorBox/ErrorBox.js +47 -49
  14. package/components/FileChooser/index.js +117 -135
  15. package/components/FormBottomBar/index.js +75 -84
  16. package/components/Icon/Icon.js +12 -20
  17. package/components/Icon/icons/index.js +256 -256
  18. package/components/IconTooltip/index.js +49 -60
  19. package/components/Map/MapBox.js +545 -452
  20. package/components/Map/MapContainer.js +25 -29
  21. package/components/Map/MapDateSliderControl.js +64 -64
  22. package/components/Map/MapDrawer.js +41 -47
  23. package/components/Map/MapLegend.js +176 -172
  24. package/components/Map/MapViewStyleControl.js +59 -63
  25. package/components/Map/ReactMapboxWrapper.js +3 -2
  26. package/components/Map/index.js +161 -180
  27. package/components/Map/types.js +12 -17
  28. package/components/Map/useMaintainLayerOrder.js +16 -26
  29. package/components/Markdown/index.js +25 -26
  30. package/components/Message/Message.js +73 -76
  31. package/components/MultiSelect/index.js +112 -124
  32. package/components/Navbar/NavFooter.js +9 -13
  33. package/components/Navbar/NavItem.js +70 -76
  34. package/components/Navbar/NavSection.js +17 -19
  35. package/components/Navbar/Navbar.js +39 -46
  36. package/components/Navbar/SubNavbar.js +9 -13
  37. package/components/Note.js +18 -22
  38. package/components/OverlayModal/OverlayModal.js +56 -63
  39. package/components/PageForm/index.js +33 -41
  40. package/components/PhotoChooser/index.js +165 -173
  41. package/components/PhotosCarousel/PhotoSlide.js +32 -35
  42. package/components/PhotosCarousel/index.js +80 -85
  43. package/components/PhotosCarousel/usePhotosCarousel.js +69 -76
  44. package/components/Pill/index.js +41 -45
  45. package/components/PillList/index.js +17 -24
  46. package/components/PlacementWrapper/index.js +38 -59
  47. package/components/PopoverMenu/Popover.js +68 -85
  48. package/components/PopoverMenu/index.js +51 -56
  49. package/components/PopoverMultiSelect/index.js +52 -59
  50. package/components/ProgressCircle/ProgressCircle.js +28 -32
  51. package/components/RadioButton.js +17 -19
  52. package/components/Select/Select.js +13 -15
  53. package/components/Select/SelectT.js +235 -250
  54. package/components/Separator/index.js +14 -17
  55. package/components/Size.js +0 -1
  56. package/components/Slider/index.js +43 -56
  57. package/components/Stepper/index.d.ts +33 -0
  58. package/components/Stepper/index.d.ts.map +1 -0
  59. package/components/Stepper/index.js +66 -0
  60. package/components/SummaryBox.js +70 -72
  61. package/components/Tabs/index.js +133 -135
  62. package/components/TextTruncated/index.js +117 -130
  63. package/components/Textfield/Textfield.js +158 -190
  64. package/components/Textfield/TruncatedTextArea.js +70 -84
  65. package/components/TimelineSlider/TimelineMarker.js +25 -30
  66. package/components/TimelineSlider/TimelineRail.js +8 -11
  67. package/components/TimelineSlider/index.js +64 -66
  68. package/components/TimelineSliderV2/ClusterBadge.js +25 -29
  69. package/components/TimelineSliderV2/TimelineDot.js +31 -35
  70. package/components/TimelineSliderV2/TimelineRail.js +8 -11
  71. package/components/TimelineSliderV2/index.js +121 -103
  72. package/components/TimelineSliderV2/layout.js +124 -147
  73. package/components/TimelineSliderV2/types.js +0 -1
  74. package/components/Tooltip/Tooltip.js +47 -56
  75. package/components/ViewPhotosDialog/index.js +28 -35
  76. package/components/VirtualWalkthrough/Annotation.js +163 -207
  77. package/components/VirtualWalkthrough/AnnotationEditPane.js +198 -184
  78. package/components/VirtualWalkthrough/AnnotationPanel.js +187 -199
  79. package/components/VirtualWalkthrough/Application.js +31 -34
  80. package/components/VirtualWalkthrough/AutoRotator.js +85 -223
  81. package/components/VirtualWalkthrough/BlockingSpinner.js +26 -28
  82. package/components/VirtualWalkthrough/BoundaryRing.js +30 -34
  83. package/components/VirtualWalkthrough/BoundaryWall.js +32 -36
  84. package/components/VirtualWalkthrough/CameraInfo.js +100 -89
  85. package/components/VirtualWalkthrough/ControlsInfoPane.js +254 -195
  86. package/components/VirtualWalkthrough/GradientSky.js +72 -73
  87. package/components/VirtualWalkthrough/SplatControls.js +209 -221
  88. package/components/VirtualWalkthrough/SplatCrop.js +21 -20
  89. package/components/VirtualWalkthrough/SplatFadeCrop.js +21 -20
  90. package/components/VirtualWalkthrough/SplatModel.js +65 -85
  91. package/components/VirtualWalkthrough/SplatRevealRain.js +41 -46
  92. package/components/VirtualWalkthrough/TfAnnotationManager.js +197 -379
  93. package/components/VirtualWalkthrough/TfXrNavigation.js +73 -162
  94. package/components/VirtualWalkthrough/VirtualWalkthroughViewer.js +438 -431
  95. package/components/VirtualWalkthrough/VrAnnotationPanel.js +18 -22
  96. package/components/VirtualWalkthrough/XrAnnotationInteraction.js +14 -17
  97. package/components/VirtualWalkthrough/XrExitButton.js +14 -17
  98. package/components/VirtualWalkthrough/XrGazeDwell.js +14 -17
  99. package/components/VirtualWalkthrough/XrPointerRay.js +14 -17
  100. package/components/VirtualWalkthrough/XrStartPose.js +67 -121
  101. package/components/VirtualWalkthrough/boundary-ring.js +87 -117
  102. package/components/VirtualWalkthrough/boundary-wall.js +175 -258
  103. package/components/VirtualWalkthrough/camera-adoption.js +18 -64
  104. package/components/VirtualWalkthrough/groundPlane.js +32 -47
  105. package/components/VirtualWalkthrough/gsplat-fade-crop-effect.js +35 -35
  106. package/components/VirtualWalkthrough/splatFormat.js +13 -47
  107. package/components/VirtualWalkthrough/useAdoptedCamera.js +23 -44
  108. package/components/VirtualWalkthrough/useRestartOnVr.js +26 -37
  109. package/components/VirtualWalkthrough/useXrRenderTuning.js +33 -54
  110. package/components/VirtualWalkthrough/vr-annotation-panel-layout.js +67 -99
  111. package/components/VirtualWalkthrough/vr-annotation-panel.js +403 -433
  112. package/components/VirtualWalkthrough/vr-annotation-scroll.js +10 -28
  113. package/components/VirtualWalkthrough/walkthrough-camera.js +204 -329
  114. package/components/VirtualWalkthrough/xr-annotation-candidate-buffer.js +39 -80
  115. package/components/VirtualWalkthrough/xr-annotation-candidates.js +6 -18
  116. package/components/VirtualWalkthrough/xr-annotation-interaction.js +31 -56
  117. package/components/VirtualWalkthrough/xr-annotation-targeting.js +22 -38
  118. package/components/VirtualWalkthrough/xr-button-arming.js +7 -17
  119. package/components/VirtualWalkthrough/xr-button-hold.js +22 -36
  120. package/components/VirtualWalkthrough/xr-exit-button-mask.js +22 -36
  121. package/components/VirtualWalkthrough/xr-exit-button.js +148 -207
  122. package/components/VirtualWalkthrough/xr-face-buttons.js +19 -29
  123. package/components/VirtualWalkthrough/xr-gaze-dwell-state.js +23 -34
  124. package/components/VirtualWalkthrough/xr-gaze-dwell.js +107 -144
  125. package/components/VirtualWalkthrough/xr-interactive-ui.js +12 -24
  126. package/components/VirtualWalkthrough/xr-pointer-ray.js +13 -20
  127. package/components/VirtualWalkthrough/xr-progress-pie-material.js +117 -88
  128. package/components/VirtualWalkthrough/xr-progress-pie.js +1 -10
  129. package/components/VirtualWalkthrough/xr-ray-quad.js +16 -30
  130. package/components/VirtualWalkthrough/xr-render-tuning.js +17 -48
  131. package/components/VirtualWalkthrough/xr-scene-bounds.js +21 -37
  132. package/components/VirtualWalkthrough/xr-start-pose.js +27 -73
  133. package/components/VirtualWalkthrough/xr-teleport-gesture.js +16 -42
  134. package/components/svg/BlobbyGrayIconImage.js +41 -39
  135. package/components/svg/BlobbyGrayIconImport.js +41 -39
  136. package/components/svg/BlobbyGrayIconUploadToTheCloud.js +41 -39
  137. package/components/svg/BlobbyIconCloudChecked.js +202 -164
  138. package/components/svg/BlobbyIconExportOrUploadPhoto.js +202 -164
  139. package/components/svg/BlobbyIconFolder.js +202 -164
  140. package/components/svg/BlobbyIconGraphReport.js +202 -164
  141. package/components/svg/BlobbyIconHappy.js +202 -164
  142. package/components/svg/BlobbyIconHeartMonitor.js +202 -164
  143. package/components/svg/BlobbyIconLeaf.js +202 -164
  144. package/components/svg/BlobbyIconLibrary.js +202 -164
  145. package/components/svg/BlobbyIconNursery.js +204 -166
  146. package/components/svg/BlobbyIconOrganization.js +202 -164
  147. package/components/svg/BlobbyIconParchment.js +202 -164
  148. package/components/svg/BlobbyIconPeople.js +202 -164
  149. package/components/svg/BlobbyIconSeedBank.js +202 -164
  150. package/components/svg/BlobbyIconSeedling.js +202 -164
  151. package/components/svg/BlobbyIconSeeds.js +202 -164
  152. package/components/svg/BlobbyIconSite.js +206 -167
  153. package/components/svg/BlobbyIconSparkles.js +202 -164
  154. package/components/svg/BlobbyIconWrench.js +202 -164
  155. package/components/svg/Bug.js +19 -21
  156. package/components/svg/Calendar.js +19 -21
  157. package/components/svg/CaretDown.js +19 -21
  158. package/components/svg/CaretLeft.js +19 -21
  159. package/components/svg/CaretRight.js +19 -21
  160. package/components/svg/CaretUp.js +19 -21
  161. package/components/svg/ChevronDown.js +19 -21
  162. package/components/svg/ChevronUp.js +19 -21
  163. package/components/svg/Close.js +19 -21
  164. package/components/svg/Critical.js +19 -21
  165. package/components/svg/Edit.js +202 -164
  166. package/components/svg/Error.js +19 -21
  167. package/components/svg/Filter.js +19 -21
  168. package/components/svg/Folder.js +19 -21
  169. package/components/svg/Help.js +19 -21
  170. package/components/svg/Home.js +19 -21
  171. package/components/svg/IconAdd.js +19 -21
  172. package/components/svg/IconArrowRight.js +21 -23
  173. package/components/svg/IconBusinessNetwork.js +19 -21
  174. package/components/svg/IconCalendar.js +19 -21
  175. package/components/svg/IconCancel.js +19 -21
  176. package/components/svg/IconChargingBattery.js +19 -21
  177. package/components/svg/IconChecklist.js +21 -23
  178. package/components/svg/IconCheckmark.js +19 -21
  179. package/components/svg/IconCoinInHand.js +19 -21
  180. package/components/svg/IconColumns.js +19 -21
  181. package/components/svg/IconComment.js +20 -22
  182. package/components/svg/IconDashboard.js +19 -21
  183. package/components/svg/IconDataMigration.js +19 -21
  184. package/components/svg/IconDocument.js +21 -23
  185. package/components/svg/IconDownloadFromTheCloud.js +21 -23
  186. package/components/svg/IconEdit.js +21 -23
  187. package/components/svg/IconExpand.js +21 -23
  188. package/components/svg/IconExport.js +19 -21
  189. package/components/svg/IconExternalLink.js +19 -21
  190. package/components/svg/IconEye.js +19 -21
  191. package/components/svg/IconEyeOff.js +19 -21
  192. package/components/svg/IconFile.js +19 -21
  193. package/components/svg/IconFolder.js +19 -21
  194. package/components/svg/IconFullScreen.js +20 -22
  195. package/components/svg/IconFutures.js +19 -21
  196. package/components/svg/IconGraphReport.js +19 -21
  197. package/components/svg/IconGrid.js +19 -21
  198. package/components/svg/IconHeartMonitor.js +19 -21
  199. package/components/svg/IconHelp.js +21 -23
  200. package/components/svg/IconHistory.js +19 -21
  201. package/components/svg/IconImport.js +19 -21
  202. package/components/svg/IconIndex.js +19 -21
  203. package/components/svg/IconLayers.js +19 -21
  204. package/components/svg/IconLibrary.js +20 -22
  205. package/components/svg/IconList.js +19 -21
  206. package/components/svg/IconLivePlant.js +19 -21
  207. package/components/svg/IconLocations.js +19 -21
  208. package/components/svg/IconMail.js +19 -21
  209. package/components/svg/IconManager.js +19 -21
  210. package/components/svg/IconMap.js +19 -21
  211. package/components/svg/IconMarker.js +19 -21
  212. package/components/svg/IconMenu.js +19 -21
  213. package/components/svg/IconMenuHorizontal.js +19 -21
  214. package/components/svg/IconModule.js +19 -21
  215. package/components/svg/IconMyLocation.js +19 -21
  216. package/components/svg/IconNote.js +21 -23
  217. package/components/svg/IconNursery.js +21 -23
  218. package/components/svg/IconOrg.js +19 -21
  219. package/components/svg/IconParchment.js +19 -21
  220. package/components/svg/IconPhoto.js +19 -21
  221. package/components/svg/IconPlantsFilled.js +19 -21
  222. package/components/svg/IconRedo.js +19 -21
  223. package/components/svg/IconRestorationSite.js +19 -21
  224. package/components/svg/IconSeedBank.js +19 -21
  225. package/components/svg/IconSeedling.js +19 -21
  226. package/components/svg/IconSettings.js +19 -21
  227. package/components/svg/IconSlice.js +19 -21
  228. package/components/svg/IconSubmit.js +19 -21
  229. package/components/svg/IconSubtract.js +21 -23
  230. package/components/svg/IconSynced.js +19 -21
  231. package/components/svg/IconTrashCan.js +19 -21
  232. package/components/svg/IconTreasureMap.js +19 -21
  233. package/components/svg/IconUnavailable.js +19 -21
  234. package/components/svg/IconUndo.js +19 -21
  235. package/components/svg/IconVariable.js +19 -21
  236. package/components/svg/IconVideo.js +30 -31
  237. package/components/svg/IconWifi.js +19 -21
  238. package/components/svg/Info.js +19 -21
  239. package/components/svg/Key.js +19 -21
  240. package/components/svg/Leaf.js +19 -21
  241. package/components/svg/Lock.js +19 -21
  242. package/components/svg/Logo.js +48 -43
  243. package/components/svg/MenuVertical.js +19 -21
  244. package/components/svg/Notification.js +19 -21
  245. package/components/svg/Person.js +19 -21
  246. package/components/svg/Plus.js +19 -21
  247. package/components/svg/RestorationSite.js +19 -21
  248. package/components/svg/Search.js +19 -21
  249. package/components/svg/Seeds.js +19 -21
  250. package/components/svg/Site.js +19 -21
  251. package/components/svg/Sparkles.js +19 -21
  252. package/components/svg/Species.js +19 -21
  253. package/components/svg/Species2.js +202 -164
  254. package/components/svg/Spinner.js +54 -48
  255. package/components/svg/Star.js +19 -21
  256. package/components/svg/Success.js +19 -21
  257. package/components/svg/SuccessFilled.js +19 -21
  258. package/components/svg/TerrawareLogoDesktop.js +55 -49
  259. package/components/svg/TerrawareLogoMobile.js +25 -26
  260. package/components/svg/Touchscreen.js +19 -21
  261. package/components/svg/UploadCloud.js +202 -164
  262. package/components/svg/Warning.js +19 -21
  263. package/components/svg/WelcomeClipboard.js +156 -133
  264. package/components/svg/index.js +129 -129
  265. package/components/table/EnhancedTableToolbar.js +68 -74
  266. package/components/table/EnhancedTableToolbarV2.js +31 -41
  267. package/components/table/TableCellRenderer.js +196 -231
  268. package/components/table/TableHeader.js +71 -73
  269. package/components/table/TableHeaderItem.js +97 -102
  270. package/components/table/density.js +18 -19
  271. package/components/table/index.js +350 -369
  272. package/components/table/sort.js +27 -52
  273. package/components/table/types.js +0 -1
  274. package/components/types/index.js +0 -1
  275. package/hooks/cameraEntityContext.js +2 -13
  276. package/hooks/useBoolean.js +17 -13
  277. package/hooks/useCameraPosition.js +56 -56
  278. package/hooks/useDevicePerformance.js +17 -17
  279. package/hooks/useXr.js +85 -87
  280. package/index.d.ts +3 -1
  281. package/index.d.ts.map +1 -1
  282. package/index.js +59 -58
  283. package/package.json +1 -1
  284. package/setupTests.js +0 -4
  285. package/strings/csv/en.csv +1 -0
  286. package/strings/csv/es.csv +1 -0
  287. package/strings/csv/fr.csv +1 -0
  288. package/strings/export.js +111 -170
  289. package/strings/index.js +25 -54
  290. package/strings/locales.js +21 -41
  291. package/strings/strings-en.d.ts +1 -0
  292. package/strings/strings-en.d.ts.map +1 -1
  293. package/strings/strings-en.js +50 -51
  294. package/strings/strings-es.d.ts +1 -0
  295. package/strings/strings-es.d.ts.map +1 -1
  296. package/strings/strings-es.js +50 -51
  297. package/strings/strings-fr.d.ts +1 -0
  298. package/strings/strings-fr.d.ts.map +1 -1
  299. package/strings/strings-fr.js +50 -51
  300. package/strings/strings-gx.d.ts +1 -0
  301. package/strings/strings-gx.d.ts.map +1 -1
  302. package/strings/strings-gx.js +50 -51
  303. package/style-dictionary-dist/TerrawareTheme.js +186 -186
  304. package/theme.js +74 -76
  305. package/utils/color.js +8 -15
  306. package/utils/date.js +42 -108
  307. package/utils/index.js +4 -4
  308. package/utils/preventDefaultEvent.js +3 -3
  309. package/utils/text.js +11 -11
  310. package/utils/useDeviceInfo.js +42 -79
  311. package/virtualWalkthrough.js +23 -23
@@ -1,104 +1,122 @@
1
- import { useRef, useState, useEffect, useMemo, useCallback } from 'react';
2
- import { useTheme } from '@mui/material';
3
- import ClusterBadge from './ClusterBadge.js';
4
- import TimelineDot from './TimelineDot.js';
5
- import TimelineRail from './TimelineRail.js';
6
- import { buildLayout, DEFAULT_CLUSTER_THRESHOLD_PX } from './layout.js';
7
- import './styles.scss';
8
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
9
-
10
- const TimelineSliderV2 = ({
11
- clusterThresholdPx = DEFAULT_CLUSTER_THRESHOLD_PX,
12
- labelEnd,
13
- labelStart,
14
- marks,
15
- onSelect,
16
- selectedMarkId
17
- }) => {
18
- const theme = useTheme();
19
- const containerRef = useRef(null);
20
- const [containerWidth, setContainerWidth] = useState(0);
21
- const [expandedClusterId, setExpandedClusterId] = useState();
22
- useEffect(() => {
23
- const node = containerRef.current;
24
- if (node === null) {
25
- return;
26
- }
27
- const measure = () => setContainerWidth(node.clientWidth);
28
- measure();
29
- const observer = new ResizeObserver(measure);
30
- observer.observe(node);
31
- return () => observer.disconnect();
32
- }, []);
33
- const layout = useMemo(() => buildLayout({
34
- containerWidth,
35
- expandedClusterId,
36
- marks,
37
- thresholdPx: clusterThresholdPx
38
- }), [clusterThresholdPx, containerWidth, expandedClusterId, marks]);
39
- useEffect(() => {
40
- if (containerWidth > 0 && expandedClusterId !== undefined && layout.band === undefined) {
41
- setExpandedClusterId(undefined);
42
- }
43
- }, [containerWidth, expandedClusterId, layout.band]);
44
- const selectedLabel = useMemo(() => marks.find(mark => mark.id === selectedMarkId)?.label, [marks, selectedMarkId]);
45
- const markNames = useMemo(() => new Map(marks.map(mark => [mark.id, mark.ariaLabel ?? mark.label])), [marks]);
46
- const nodeAriaLabel = useCallback(node => {
47
- const names = node.markIds.map(markId => markNames.get(markId)).filter(name => name !== undefined);
48
- return names.length > 0 ? names.join(', ') : undefined;
49
- }, [markNames]);
50
- const handleNodeClick = useCallback(node => {
51
- if (node.markIds.length > 1) {
52
- setExpandedClusterId(node.id);
53
- } else {
54
- onSelect?.(node.markIds[0]);
55
- }
56
- }, [onSelect]);
57
- const handleCollapse = useCallback(() => setExpandedClusterId(undefined), []);
58
- return /*#__PURE__*/jsxs("div", {
59
- className: "timeline-v2",
60
- children: [/*#__PURE__*/jsx("div", {
61
- className: "timeline-v2-label",
62
- style: {
63
- marginRight: theme.spacing(2)
64
- },
65
- children: labelStart
66
- }), /*#__PURE__*/jsxs("div", {
67
- className: "timeline-v2-container",
68
- ref: containerRef,
69
- children: [/*#__PURE__*/jsx(TimelineRail, {}), layout.band && /*#__PURE__*/jsxs(Fragment, {
70
- children: [/*#__PURE__*/jsx("div", {
71
- className: "timeline-v2-band",
72
- style: {
73
- left: `${layout.band.leftPx}px`,
74
- width: `${layout.band.widthPx}px`
75
- }
76
- }), /*#__PURE__*/jsx(ClusterBadge, {
77
- count: layout.band.memberCount,
78
- leftPx: layout.band.leftPx + layout.band.widthPx / 2,
79
- onClose: handleCollapse
80
- })]
81
- }), layout.nodes.map(node => /*#__PURE__*/jsx(TimelineDot, {
82
- ariaLabel: nodeAriaLabel(node),
83
- colorWeights: node.colorWeights,
84
- dimmed: node.dimmed,
85
- leftPx: node.leftPx,
86
- markCount: node.markIds.length,
87
- onClick: () => handleNodeClick(node),
88
- selected: selectedMarkId !== undefined && node.markIds.includes(selectedMarkId),
89
- sizePx: node.sizePx
90
- }, node.id))]
91
- }), /*#__PURE__*/jsx("div", {
92
- className: "timeline-v2-label",
93
- style: {
94
- marginLeft: theme.spacing(2)
95
- },
96
- children: labelEnd
97
- }), selectedLabel && /*#__PURE__*/jsx("div", {
98
- className: "timeline-v2-selected-label",
99
- children: selectedLabel
100
- })]
101
- });
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
+ import { useTheme } from "@mui/material";
4
+ import ClusterBadge from "./ClusterBadge.js";
5
+ import TimelineDot from "./TimelineDot.js";
6
+ import TimelineRail from "./TimelineRail.js";
7
+ import { DEFAULT_CLUSTER_THRESHOLD_PX, buildLayout } from "./layout.js";
8
+ import "./styles.scss";
9
+ const TimelineSliderV2 = ({ clusterThresholdPx = DEFAULT_CLUSTER_THRESHOLD_PX, labelEnd, labelStart, marks, onSelect, selectedMarkId })=>{
10
+ const theme = useTheme();
11
+ const containerRef = useRef(null);
12
+ const [containerWidth, setContainerWidth] = useState(0);
13
+ const [expandedClusterId, setExpandedClusterId] = useState();
14
+ useEffect(()=>{
15
+ const node = containerRef.current;
16
+ if (null === node) return;
17
+ const measure = ()=>setContainerWidth(node.clientWidth);
18
+ measure();
19
+ const observer = new ResizeObserver(measure);
20
+ observer.observe(node);
21
+ return ()=>observer.disconnect();
22
+ }, []);
23
+ const layout = useMemo(()=>buildLayout({
24
+ containerWidth,
25
+ expandedClusterId,
26
+ marks,
27
+ thresholdPx: clusterThresholdPx
28
+ }), [
29
+ clusterThresholdPx,
30
+ containerWidth,
31
+ expandedClusterId,
32
+ marks
33
+ ]);
34
+ useEffect(()=>{
35
+ if (containerWidth > 0 && void 0 !== expandedClusterId && void 0 === layout.band) setExpandedClusterId(void 0);
36
+ }, [
37
+ containerWidth,
38
+ expandedClusterId,
39
+ layout.band
40
+ ]);
41
+ const selectedLabel = useMemo(()=>marks.find((mark)=>mark.id === selectedMarkId)?.label, [
42
+ marks,
43
+ selectedMarkId
44
+ ]);
45
+ const markNames = useMemo(()=>new Map(marks.map((mark)=>[
46
+ mark.id,
47
+ mark.ariaLabel ?? mark.label
48
+ ])), [
49
+ marks
50
+ ]);
51
+ const nodeAriaLabel = useCallback((node)=>{
52
+ const names = node.markIds.map((markId)=>markNames.get(markId)).filter((name)=>void 0 !== name);
53
+ return names.length > 0 ? names.join(', ') : void 0;
54
+ }, [
55
+ markNames
56
+ ]);
57
+ const handleNodeClick = useCallback((node)=>{
58
+ if (node.markIds.length > 1) setExpandedClusterId(node.id);
59
+ else onSelect?.(node.markIds[0]);
60
+ }, [
61
+ onSelect
62
+ ]);
63
+ const handleCollapse = useCallback(()=>setExpandedClusterId(void 0), []);
64
+ return /*#__PURE__*/ jsxs("div", {
65
+ className: "timeline-v2",
66
+ children: [
67
+ /*#__PURE__*/ jsx("div", {
68
+ className: "timeline-v2-label",
69
+ style: {
70
+ marginRight: theme.spacing(2)
71
+ },
72
+ children: labelStart
73
+ }),
74
+ /*#__PURE__*/ jsxs("div", {
75
+ className: "timeline-v2-container",
76
+ ref: containerRef,
77
+ children: [
78
+ /*#__PURE__*/ jsx(TimelineRail, {}),
79
+ layout.band && /*#__PURE__*/ jsxs(Fragment, {
80
+ children: [
81
+ /*#__PURE__*/ jsx("div", {
82
+ className: "timeline-v2-band",
83
+ style: {
84
+ left: `${layout.band.leftPx}px`,
85
+ width: `${layout.band.widthPx}px`
86
+ }
87
+ }),
88
+ /*#__PURE__*/ jsx(ClusterBadge, {
89
+ count: layout.band.memberCount,
90
+ leftPx: layout.band.leftPx + layout.band.widthPx / 2,
91
+ onClose: handleCollapse
92
+ })
93
+ ]
94
+ }),
95
+ layout.nodes.map((node)=>/*#__PURE__*/ jsx(TimelineDot, {
96
+ ariaLabel: nodeAriaLabel(node),
97
+ colorWeights: node.colorWeights,
98
+ dimmed: node.dimmed,
99
+ leftPx: node.leftPx,
100
+ markCount: node.markIds.length,
101
+ onClick: ()=>handleNodeClick(node),
102
+ selected: void 0 !== selectedMarkId && node.markIds.includes(selectedMarkId),
103
+ sizePx: node.sizePx
104
+ }, node.id))
105
+ ]
106
+ }),
107
+ /*#__PURE__*/ jsx("div", {
108
+ className: "timeline-v2-label",
109
+ style: {
110
+ marginLeft: theme.spacing(2)
111
+ },
112
+ children: labelEnd
113
+ }),
114
+ selectedLabel && /*#__PURE__*/ jsx("div", {
115
+ className: "timeline-v2-selected-label",
116
+ children: selectedLabel
117
+ })
118
+ ]
119
+ });
102
120
  };
103
-
104
- export { TimelineSliderV2 as default };
121
+ const components_TimelineSliderV2 = TimelineSliderV2;
122
+ export default components_TimelineSliderV2;
@@ -7,162 +7,139 @@ const SQUEEZE_GAP_PX = 12;
7
7
  const MAX_BAND_RATIO = 0.8;
8
8
  const DEFAULT_CLUSTER_THRESHOLD_PX = 16;
9
9
  const DIMMED_OPACITY = 0.35;
10
- const normalizePositions = (marks, containerWidth) => {
11
- if (marks.length === 0) {
12
- return [];
13
- }
14
- const values = marks.map(mark => mark.value);
15
- const minValue = Math.min(...values);
16
- const maxValue = Math.max(...values);
17
- const range = maxValue - minValue;
18
-
19
- // Mirrors TimelineSlider's behavior: when every mark shares one value, they all land at the right edge.
20
- return marks.map(mark => ({
21
- color: mark.color,
22
- id: mark.id,
23
- positionPx: (range === 0 ? 1 : (mark.value - minValue) / range) * containerWidth
24
- })).sort((a, b) => a.positionPx - b.positionPx);
10
+ const normalizePositions = (marks, containerWidth)=>{
11
+ if (0 === marks.length) return [];
12
+ const values = marks.map((mark)=>mark.value);
13
+ const minValue = Math.min(...values);
14
+ const maxValue = Math.max(...values);
15
+ const range = maxValue - minValue;
16
+ return marks.map((mark)=>({
17
+ color: mark.color,
18
+ id: mark.id,
19
+ positionPx: (0 === range ? 1 : (mark.value - minValue) / range) * containerWidth
20
+ })).sort((a, b)=>a.positionPx - b.positionPx);
25
21
  };
26
- const toColorWeights = colors => {
27
- const weights = new Map();
28
- colors.forEach(color => {
29
- weights.set(color, (weights.get(color) ?? 0) + 1);
30
- });
31
- return [...weights.entries()].map(([color, weight]) => ({
32
- color,
33
- weight
34
- }));
22
+ const toColorWeights = (colors)=>{
23
+ const weights = new Map();
24
+ colors.forEach((color)=>{
25
+ weights.set(color, (weights.get(color) ?? 0) + 1);
26
+ });
27
+ return [
28
+ ...weights.entries()
29
+ ].map(([color, weight])=>({
30
+ color,
31
+ weight
32
+ }));
35
33
  };
36
- const buildClusters = (marks, containerWidth, thresholdPx) => {
37
- const positioned = normalizePositions(marks, containerWidth);
38
- const clusters = [];
39
- let current = [];
40
- const flush = () => {
41
- if (current.length === 0) {
42
- return;
43
- }
44
- const total = current.reduce((sum, member) => sum + member.positionPx, 0);
45
- clusters.push({
46
- anchorPx: total / current.length,
47
- id: `cluster-${current[0].id}`,
48
- members: current
34
+ const buildClusters = (marks, containerWidth, thresholdPx)=>{
35
+ const positioned = normalizePositions(marks, containerWidth);
36
+ const clusters = [];
37
+ let current = [];
38
+ const flush = ()=>{
39
+ if (0 === current.length) return;
40
+ const total = current.reduce((sum, member)=>sum + member.positionPx, 0);
41
+ clusters.push({
42
+ anchorPx: total / current.length,
43
+ id: `cluster-${current[0].id}`,
44
+ members: current
45
+ });
46
+ current = [];
47
+ };
48
+ positioned.forEach((mark)=>{
49
+ const previous = current[current.length - 1];
50
+ if (void 0 !== previous && mark.positionPx - previous.positionPx >= thresholdPx) flush();
51
+ current.push(mark);
49
52
  });
50
- current = [];
51
- };
52
- positioned.forEach(mark => {
53
- const previous = current[current.length - 1];
54
- if (previous !== undefined && mark.positionPx - previous.positionPx >= thresholdPx) {
55
- flush();
56
- }
57
- current.push(mark);
58
- });
59
- flush();
60
- return clusters;
53
+ flush();
54
+ return clusters;
61
55
  };
62
- const toConicGradient = colorWeights => {
63
- if (colorWeights.length <= 1) {
64
- return colorWeights[0]?.color ?? 'transparent';
65
- }
66
- const total = colorWeights.reduce((sum, {
67
- weight
68
- }) => sum + weight, 0);
69
- let consumed = 0;
70
- const stops = colorWeights.map(({
71
- color,
72
- weight
73
- }) => {
74
- const startDeg = consumed / total * 360;
75
- consumed += weight;
76
- const endDeg = consumed / total * 360;
77
- return `${color} ${startDeg}deg ${endDeg}deg`;
78
- });
79
- return `conic-gradient(${stops.join(', ')})`;
56
+ const toConicGradient = (colorWeights)=>{
57
+ if (colorWeights.length <= 1) return colorWeights[0]?.color ?? 'transparent';
58
+ const total = colorWeights.reduce((sum, { weight })=>sum + weight, 0);
59
+ let consumed = 0;
60
+ const stops = colorWeights.map(({ color, weight })=>{
61
+ const startDeg = consumed / total * 360;
62
+ consumed += weight;
63
+ const endDeg = consumed / total * 360;
64
+ return `${color} ${startDeg}deg ${endDeg}deg`;
65
+ });
66
+ return `conic-gradient(${stops.join(', ')})`;
80
67
  };
81
- const toCollapsedNode = (cluster, dimmed) => ({
82
- colorWeights: toColorWeights(cluster.members.map(member => member.color)),
83
- dimmed,
84
- id: cluster.id,
85
- leftPx: cluster.anchorPx,
86
- markIds: cluster.members.map(member => member.id),
87
- sizePx: cluster.members.length > 1 ? CLUSTER_DOT_SIZE_PX : DOT_SIZE_PX
88
- });
89
- const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
90
- const expandedSpacing = (memberCount, containerWidth, maxBandWidth) => {
91
- if (memberCount <= 1) {
92
- return EXPANDED_SPACING_PX;
93
- }
94
- const cap = Math.min(containerWidth * MAX_BAND_RATIO, maxBandWidth);
95
- const fitted = (cap - DOT_SIZE_PX - 2 * BAND_PADDING_PX) / (memberCount - 1);
96
- return Math.max(0, Math.min(EXPANDED_SPACING_PX, fitted));
68
+ const toCollapsedNode = (cluster, dimmed)=>({
69
+ colorWeights: toColorWeights(cluster.members.map((member)=>member.color)),
70
+ dimmed,
71
+ id: cluster.id,
72
+ leftPx: cluster.anchorPx,
73
+ markIds: cluster.members.map((member)=>member.id),
74
+ sizePx: cluster.members.length > 1 ? CLUSTER_DOT_SIZE_PX : DOT_SIZE_PX
75
+ });
76
+ const clamp = (value, min, max)=>Math.min(Math.max(value, min), max);
77
+ const expandedSpacing = (memberCount, containerWidth, maxBandWidth)=>{
78
+ if (memberCount <= 1) return EXPANDED_SPACING_PX;
79
+ const cap = Math.min(containerWidth * MAX_BAND_RATIO, maxBandWidth);
80
+ const fitted = (cap - DOT_SIZE_PX - 2 * BAND_PADDING_PX) / (memberCount - 1);
81
+ return Math.max(0, Math.min(EXPANDED_SPACING_PX, fitted));
97
82
  };
98
- const rescale = (value, fromStart, fromEnd, toStart, toEnd) => {
99
- const fromSpan = fromEnd - fromStart;
100
- if (fromSpan <= 0) {
101
- return toStart;
102
- }
103
- return toStart + (value - fromStart) / fromSpan * (toEnd - toStart);
83
+ const rescale = (value, fromStart, fromEnd, toStart, toEnd)=>{
84
+ const fromSpan = fromEnd - fromStart;
85
+ if (fromSpan <= 0) return toStart;
86
+ return toStart + (value - fromStart) / fromSpan * (toEnd - toStart);
104
87
  };
105
- const buildLayout = ({
106
- containerWidth,
107
- expandedClusterId,
108
- marks,
109
- thresholdPx = DEFAULT_CLUSTER_THRESHOLD_PX
110
- }) => {
111
- if (containerWidth <= 0 || marks.length === 0) {
112
- return {
113
- nodes: []
88
+ const buildLayout = ({ containerWidth, expandedClusterId, marks, thresholdPx = DEFAULT_CLUSTER_THRESHOLD_PX })=>{
89
+ if (containerWidth <= 0 || 0 === marks.length) return {
90
+ nodes: []
91
+ };
92
+ const clusters = buildClusters(marks, containerWidth, thresholdPx);
93
+ const expanded = clusters.find((cluster)=>cluster.id === expandedClusterId && cluster.members.length > 1);
94
+ if (void 0 === expanded) return {
95
+ nodes: clusters.map((cluster)=>toCollapsedNode(cluster, false))
114
96
  };
115
- }
116
- const clusters = buildClusters(marks, containerWidth, thresholdPx);
117
- const expanded = clusters.find(cluster => cluster.id === expandedClusterId && cluster.members.length > 1);
118
- if (expanded === undefined) {
97
+ const sideClusters = clusters.filter((cluster)=>cluster.id !== expanded.id);
98
+ const leftCount = sideClusters.filter((cluster)=>cluster.anchorPx < expanded.anchorPx).length;
99
+ const rightCount = sideClusters.length - leftCount;
100
+ const reserve = (count)=>0 === count ? 0 : SQUEEZE_GAP_PX + (count - 1) * MIN_SQUEEZE_PITCH_PX;
101
+ const leftReserve = reserve(leftCount);
102
+ const rightReserve = reserve(rightCount);
103
+ const minBandWidth = DOT_SIZE_PX + 2 * BAND_PADDING_PX;
104
+ const maxBandWidth = Math.max(minBandWidth, containerWidth - leftReserve - rightReserve);
105
+ const spacing = expandedSpacing(expanded.members.length, containerWidth, maxBandWidth);
106
+ const widthPx = Math.min(maxBandWidth, (expanded.members.length - 1) * spacing + minBandWidth);
107
+ const leftPx = clamp(expanded.anchorPx - widthPx / 2, leftReserve, Math.max(leftReserve, containerWidth - widthPx - rightReserve));
108
+ const band = {
109
+ leftPx,
110
+ memberCount: expanded.members.length,
111
+ widthPx
112
+ };
113
+ const leftLimit = Math.max(0, leftPx - SQUEEZE_GAP_PX);
114
+ const rightLimit = Math.min(containerWidth, leftPx + widthPx + SQUEEZE_GAP_PX);
115
+ const nodes = clusters.flatMap((cluster)=>{
116
+ if (cluster.id === expanded.id) return cluster.members.map((member, index)=>({
117
+ colorWeights: [
118
+ {
119
+ color: member.color,
120
+ weight: 1
121
+ }
122
+ ],
123
+ dimmed: false,
124
+ id: member.id,
125
+ leftPx: leftPx + BAND_PADDING_PX + DOT_SIZE_PX / 2 + index * spacing,
126
+ markIds: [
127
+ member.id
128
+ ],
129
+ sizePx: DOT_SIZE_PX
130
+ }));
131
+ const collapsed = toCollapsedNode(cluster, true);
132
+ const squeezed = cluster.anchorPx < expanded.anchorPx ? rescale(cluster.anchorPx, 0, expanded.anchorPx, 0, leftLimit) : rescale(cluster.anchorPx, expanded.anchorPx, containerWidth, rightLimit, containerWidth);
133
+ return [
134
+ {
135
+ ...collapsed,
136
+ leftPx: squeezed
137
+ }
138
+ ];
139
+ });
119
140
  return {
120
- nodes: clusters.map(cluster => toCollapsedNode(cluster, false))
141
+ band,
142
+ nodes
121
143
  };
122
- }
123
- const sideClusters = clusters.filter(cluster => cluster.id !== expanded.id);
124
- const leftCount = sideClusters.filter(cluster => cluster.anchorPx < expanded.anchorPx).length;
125
- const rightCount = sideClusters.length - leftCount;
126
- const reserve = count => count === 0 ? 0 : SQUEEZE_GAP_PX + (count - 1) * MIN_SQUEEZE_PITCH_PX;
127
- const leftReserve = reserve(leftCount);
128
- const rightReserve = reserve(rightCount);
129
- const minBandWidth = DOT_SIZE_PX + 2 * BAND_PADDING_PX;
130
- const maxBandWidth = Math.max(minBandWidth, containerWidth - leftReserve - rightReserve);
131
- const spacing = expandedSpacing(expanded.members.length, containerWidth, maxBandWidth);
132
- const widthPx = Math.min(maxBandWidth, (expanded.members.length - 1) * spacing + minBandWidth);
133
- const leftPx = clamp(expanded.anchorPx - widthPx / 2, leftReserve, Math.max(leftReserve, containerWidth - widthPx - rightReserve));
134
- const band = {
135
- leftPx,
136
- memberCount: expanded.members.length,
137
- widthPx
138
- };
139
- const leftLimit = Math.max(0, leftPx - SQUEEZE_GAP_PX);
140
- const rightLimit = Math.min(containerWidth, leftPx + widthPx + SQUEEZE_GAP_PX);
141
- const nodes = clusters.flatMap(cluster => {
142
- if (cluster.id === expanded.id) {
143
- return cluster.members.map((member, index) => ({
144
- colorWeights: [{
145
- color: member.color,
146
- weight: 1
147
- }],
148
- dimmed: false,
149
- id: member.id,
150
- leftPx: leftPx + BAND_PADDING_PX + DOT_SIZE_PX / 2 + index * spacing,
151
- markIds: [member.id],
152
- sizePx: DOT_SIZE_PX
153
- }));
154
- }
155
- const collapsed = toCollapsedNode(cluster, true);
156
- const squeezed = cluster.anchorPx < expanded.anchorPx ? rescale(cluster.anchorPx, 0, expanded.anchorPx, 0, leftLimit) : rescale(cluster.anchorPx, expanded.anchorPx, containerWidth, rightLimit, containerWidth);
157
- return [{
158
- ...collapsed,
159
- leftPx: squeezed
160
- }];
161
- });
162
- return {
163
- band,
164
- nodes
165
- };
166
144
  };
167
-
168
145
  export { BAND_PADDING_PX, CLUSTER_DOT_SIZE_PX, DEFAULT_CLUSTER_THRESHOLD_PX, DIMMED_OPACITY, DOT_SIZE_PX, EXPANDED_SPACING_PX, MAX_BAND_RATIO, MIN_SQUEEZE_PITCH_PX, SQUEEZE_GAP_PX, buildClusters, buildLayout, normalizePositions, toColorWeights, toConicGradient };
@@ -1 +0,0 @@
1
-
@@ -1,57 +1,48 @@
1
- import React from 'react';
2
- import { useTheme, Tooltip as Tooltip$1 } from '@mui/material';
3
- import 'lodash';
4
- import 'luxon';
5
- import useDeviceInfo from '../../utils/useDeviceInfo.js';
6
- import { jsx } from 'react/jsx-runtime';
7
-
8
- function Tooltip({
9
- children,
10
- placement = 'top-start',
11
- slotProps,
12
- sx,
13
- title
14
- }) {
15
- const [open, setOpen] = React.useState(false);
16
- const {
17
- isMobile
18
- } = useDeviceInfo();
19
- const theme = useTheme();
20
- const handleTooltipClose = () => {
21
- setOpen(false);
22
- };
23
- const handleTooltipOpen = event => {
24
- if (event.type === 'click' || event.type === 'mouseover' && !isMobile) {
25
- setOpen(true);
26
- }
27
- };
28
- return /*#__PURE__*/jsx(Tooltip$1, {
29
- arrow: true,
30
- onOpen: handleTooltipOpen,
31
- onClose: handleTooltipClose,
32
- open: open,
33
- placement: placement,
34
- slotProps: slotProps,
35
- sx: [{
36
- maxWidth: isMobile ? '342px' : '464px',
37
- '& .MuiTooltip-arrow': {
38
- color: theme.palette.TwClrBaseGray800
39
- },
40
- '& .MuiTooltip-tooltip': {
41
- backgroundColor: theme.palette.TwClrBaseGray800,
42
- color: theme.palette.TwClrBaseWhite,
43
- padding: '8px',
44
- '& a': {
45
- color: theme.palette.TwClrBaseWhite
46
- }
47
- }
48
- }, ...(Array.isArray(sx) ? sx : [sx])],
49
- title: title,
50
- children: /*#__PURE__*/jsx("span", {
51
- onClick: handleTooltipOpen,
52
- children: children
53
- })
54
- });
1
+ import { jsx } from "react/jsx-runtime";
2
+ import react from "react";
3
+ import { Tooltip, useTheme } from "@mui/material";
4
+ import { useDeviceInfo } from "../../utils/index.js";
5
+ function Tooltip_Tooltip({ children, placement = 'top-start', slotProps, sx, title }) {
6
+ const [open, setOpen] = react.useState(false);
7
+ const { isMobile } = useDeviceInfo();
8
+ const theme = useTheme();
9
+ const handleTooltipClose = ()=>{
10
+ setOpen(false);
11
+ };
12
+ const handleTooltipOpen = (event)=>{
13
+ if ('click' === event.type || 'mouseover' === event.type && !isMobile) setOpen(true);
14
+ };
15
+ return /*#__PURE__*/ jsx(Tooltip, {
16
+ arrow: true,
17
+ onOpen: handleTooltipOpen,
18
+ onClose: handleTooltipClose,
19
+ open: open,
20
+ placement: placement,
21
+ slotProps: slotProps,
22
+ sx: [
23
+ {
24
+ maxWidth: isMobile ? '342px' : '464px',
25
+ '& .MuiTooltip-arrow': {
26
+ color: theme.palette.TwClrBaseGray800
27
+ },
28
+ '& .MuiTooltip-tooltip': {
29
+ backgroundColor: theme.palette.TwClrBaseGray800,
30
+ color: theme.palette.TwClrBaseWhite,
31
+ padding: '8px',
32
+ '& a': {
33
+ color: theme.palette.TwClrBaseWhite
34
+ }
35
+ }
36
+ },
37
+ ...Array.isArray(sx) ? sx : [
38
+ sx
39
+ ]
40
+ ],
41
+ title: title,
42
+ children: /*#__PURE__*/ jsx("span", {
43
+ onClick: handleTooltipOpen,
44
+ children: children
45
+ })
46
+ });
55
47
  }
56
-
57
- export { Tooltip as default };
48
+ export default Tooltip_Tooltip;