@zendir/ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (359) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +589 -0
  4. package/dist/index.d.ts +8 -0
  5. package/dist/index.js +421 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/react/3d/EarthViewer.d.ts +46 -0
  8. package/dist/react/3d/EarthViewer.js +836 -0
  9. package/dist/react/3d/EarthViewer.js.map +1 -0
  10. package/dist/react/3d/SolarSystemViewer.d.ts +43 -0
  11. package/dist/react/3d/SolarSystemViewer.js +372 -0
  12. package/dist/react/3d/SolarSystemViewer.js.map +1 -0
  13. package/dist/react/3d/ZenSpace3D.d.ts +16 -0
  14. package/dist/react/3d/ZenSpace3D.js +1253 -0
  15. package/dist/react/3d/ZenSpace3D.js.map +1 -0
  16. package/dist/react/3d/ZenSpace3DCesium.d.ts +9 -0
  17. package/dist/react/3d/ZenSpace3DCesium.js +186 -0
  18. package/dist/react/3d/ZenSpace3DCesium.js.map +1 -0
  19. package/dist/react/3d/ZenSpace3DShaders.d.ts +78 -0
  20. package/dist/react/3d/ZenSpace3DShaders.js +94 -0
  21. package/dist/react/3d/ZenSpace3DShaders.js.map +1 -0
  22. package/dist/react/3d/ZenSpace3DTypes.d.ts +614 -0
  23. package/dist/react/3d/ZenSpace3DUtils.d.ts +183 -0
  24. package/dist/react/3d/ZenSpace3DUtils.js +213 -0
  25. package/dist/react/3d/ZenSpace3DUtils.js.map +1 -0
  26. package/dist/react/3d/index.d.ts +23 -0
  27. package/dist/react/3d/threeLoader.d.ts +22 -0
  28. package/dist/react/3d/threeLoader.js +18 -0
  29. package/dist/react/3d/threeLoader.js.map +1 -0
  30. package/dist/react/astro/ClassificationBanner.d.ts +25 -0
  31. package/dist/react/astro/ClassificationBanner.js +83 -0
  32. package/dist/react/astro/ClassificationBanner.js.map +1 -0
  33. package/dist/react/astro/GlobalStatusBar.d.ts +42 -0
  34. package/dist/react/astro/GlobalStatusBar.js +165 -0
  35. package/dist/react/astro/GlobalStatusBar.js.map +1 -0
  36. package/dist/react/astro/MissionClock.d.ts +169 -0
  37. package/dist/react/astro/MissionClock.js +411 -0
  38. package/dist/react/astro/MissionClock.js.map +1 -0
  39. package/dist/react/astro/MonitoringIcon.d.ts +60 -0
  40. package/dist/react/astro/MonitoringIcon.js +369 -0
  41. package/dist/react/astro/MonitoringIcon.js.map +1 -0
  42. package/dist/react/astro/Notification.d.ts +42 -0
  43. package/dist/react/astro/Notification.js +156 -0
  44. package/dist/react/astro/Notification.js.map +1 -0
  45. package/dist/react/astro/Progress.d.ts +39 -0
  46. package/dist/react/astro/Progress.js +149 -0
  47. package/dist/react/astro/Progress.js.map +1 -0
  48. package/dist/react/astro/SimulationControls.d.ts +136 -0
  49. package/dist/react/astro/SimulationControls.js +668 -0
  50. package/dist/react/astro/SimulationControls.js.map +1 -0
  51. package/dist/react/astro/StatusIndicator.d.ts +34 -0
  52. package/dist/react/astro/StatusIndicator.js +189 -0
  53. package/dist/react/astro/StatusIndicator.js.map +1 -0
  54. package/dist/react/astro/UnifiedTimeline.d.ts +106 -0
  55. package/dist/react/astro/UnifiedTimeline.js +1768 -0
  56. package/dist/react/astro/UnifiedTimeline.js.map +1 -0
  57. package/dist/react/astro/index.d.ts +63 -0
  58. package/dist/react/cards/AccessCard.d.ts +37 -0
  59. package/dist/react/cards/AccessCard.js +410 -0
  60. package/dist/react/cards/AccessCard.js.map +1 -0
  61. package/dist/react/cards/OrbitCard.d.ts +31 -0
  62. package/dist/react/cards/OrbitCard.js +372 -0
  63. package/dist/react/cards/OrbitCard.js.map +1 -0
  64. package/dist/react/cards/SpacecraftCard.d.ts +54 -0
  65. package/dist/react/cards/SpacecraftCard.js +941 -0
  66. package/dist/react/cards/SpacecraftCard.js.map +1 -0
  67. package/dist/react/cards/TelemetryCard.d.ts +40 -0
  68. package/dist/react/cards/TelemetryCard.js +742 -0
  69. package/dist/react/cards/TelemetryCard.js.map +1 -0
  70. package/dist/react/cards/TelemetryStreamCard.d.ts +59 -0
  71. package/dist/react/cards/TelemetryStreamCard.js +309 -0
  72. package/dist/react/cards/TelemetryStreamCard.js.map +1 -0
  73. package/dist/react/cards/index.d.ts +13 -0
  74. package/dist/react/charts/GroundTrackMap.d.ts +112 -0
  75. package/dist/react/charts/GroundTrackMap.js +1123 -0
  76. package/dist/react/charts/GroundTrackMap.js.map +1 -0
  77. package/dist/react/charts/GroundTrackMapLeaflet.d.ts +26 -0
  78. package/dist/react/charts/GroundTrackMapLeaflet.js +571 -0
  79. package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -0
  80. package/dist/react/charts/groundTrackMapLeafletTiles.d.ts +22 -0
  81. package/dist/react/charts/groundTrackMapLeafletTiles.js +11 -0
  82. package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -0
  83. package/dist/react/charts/groundTrackMapLeafletUtils.d.ts +24 -0
  84. package/dist/react/charts/groundTrackMapLeafletUtils.js +109 -0
  85. package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -0
  86. package/dist/react/charts/index.d.ts +10 -0
  87. package/dist/react/charts/unified/AstroChart.d.ts +24 -0
  88. package/dist/react/charts/unified/AstroChart.js +1405 -0
  89. package/dist/react/charts/unified/AstroChart.js.map +1 -0
  90. package/dist/react/charts/unified/PowerOverviewChart.d.ts +73 -0
  91. package/dist/react/charts/unified/PowerOverviewChart.js +488 -0
  92. package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -0
  93. package/dist/react/charts/unified/domain.d.ts +845 -0
  94. package/dist/react/charts/unified/domain.js +3168 -0
  95. package/dist/react/charts/unified/domain.js.map +1 -0
  96. package/dist/react/charts/unified/generators.d.ts +276 -0
  97. package/dist/react/charts/unified/generators.js +518 -0
  98. package/dist/react/charts/unified/generators.js.map +1 -0
  99. package/dist/react/charts/unified/index.d.ts +55 -0
  100. package/dist/react/charts/unified/presets.d.ts +290 -0
  101. package/dist/react/charts/unified/presets.js +999 -0
  102. package/dist/react/charts/unified/presets.js.map +1 -0
  103. package/dist/react/charts/unified/sync.d.ts +69 -0
  104. package/dist/react/charts/unified/sync.js +219 -0
  105. package/dist/react/charts/unified/sync.js.map +1 -0
  106. package/dist/react/charts/unified/theme.d.ts +447 -0
  107. package/dist/react/charts/unified/theme.js +562 -0
  108. package/dist/react/charts/unified/theme.js.map +1 -0
  109. package/dist/react/charts/unified/types.d.ts +826 -0
  110. package/dist/react/charts/unified/useChartStream.d.ts +58 -0
  111. package/dist/react/charts/unified/useChartStream.js +226 -0
  112. package/dist/react/charts/unified/useChartStream.js.map +1 -0
  113. package/dist/react/chatgpt/AppCard.d.ts +59 -0
  114. package/dist/react/chatgpt/AppCard.js +306 -0
  115. package/dist/react/chatgpt/AppCard.js.map +1 -0
  116. package/dist/react/chatgpt/ChatGPTCard.d.ts +6 -0
  117. package/dist/react/chatgpt/index.d.ts +167 -0
  118. package/dist/react/chatgpt/index.js +166 -0
  119. package/dist/react/chatgpt/index.js.map +1 -0
  120. package/dist/react/context/DisplaySettingsContext.d.ts +107 -0
  121. package/dist/react/context/DisplaySettingsContext.js +169 -0
  122. package/dist/react/context/DisplaySettingsContext.js.map +1 -0
  123. package/dist/react/context/index.d.ts +5 -0
  124. package/dist/react/core/ActivityPlanner.d.ts +45 -0
  125. package/dist/react/core/ActivityPlanner.js +532 -0
  126. package/dist/react/core/ActivityPlanner.js.map +1 -0
  127. package/dist/react/core/AppBar.d.ts +71 -0
  128. package/dist/react/core/AppBar.js +817 -0
  129. package/dist/react/core/AppBar.js.map +1 -0
  130. package/dist/react/core/AstroIcon.d.ts +84 -0
  131. package/dist/react/core/AstroIcon.js +1243 -0
  132. package/dist/react/core/AstroIcon.js.map +1 -0
  133. package/dist/react/core/Badge.d.ts +27 -0
  134. package/dist/react/core/Badge.js +134 -0
  135. package/dist/react/core/Badge.js.map +1 -0
  136. package/dist/react/core/Button.d.ts +26 -0
  137. package/dist/react/core/Button.js +306 -0
  138. package/dist/react/core/Button.js.map +1 -0
  139. package/dist/react/core/CardHeader.d.ts +34 -0
  140. package/dist/react/core/CardHeader.js +316 -0
  141. package/dist/react/core/CardHeader.js.map +1 -0
  142. package/dist/react/core/ChatPanel.d.ts +627 -0
  143. package/dist/react/core/ChatPanel.js +1144 -0
  144. package/dist/react/core/ChatPanel.js.map +1 -0
  145. package/dist/react/core/Checkbox.d.ts +26 -0
  146. package/dist/react/core/Checkbox.js +130 -0
  147. package/dist/react/core/Checkbox.js.map +1 -0
  148. package/dist/react/core/ColorPickerPanel.d.ts +25 -0
  149. package/dist/react/core/ColorPickerPanel.js +293 -0
  150. package/dist/react/core/ColorPickerPanel.js.map +1 -0
  151. package/dist/react/core/CommandBuilder.d.ts +74 -0
  152. package/dist/react/core/CommandBuilder.js +518 -0
  153. package/dist/react/core/CommandBuilder.js.map +1 -0
  154. package/dist/react/core/ConfirmDialog.d.ts +45 -0
  155. package/dist/react/core/ConfirmDialog.js +315 -0
  156. package/dist/react/core/ConfirmDialog.js.map +1 -0
  157. package/dist/react/core/ConnectionForm.d.ts +57 -0
  158. package/dist/react/core/ConnectionForm.js +496 -0
  159. package/dist/react/core/ConnectionForm.js.map +1 -0
  160. package/dist/react/core/Container.d.ts +51 -0
  161. package/dist/react/core/Container.js +670 -0
  162. package/dist/react/core/Container.js.map +1 -0
  163. package/dist/react/core/CopyButton.d.ts +39 -0
  164. package/dist/react/core/CopyButton.js +105 -0
  165. package/dist/react/core/CopyButton.js.map +1 -0
  166. package/dist/react/core/DataTable.d.ts +113 -0
  167. package/dist/react/core/DataTable.js +446 -0
  168. package/dist/react/core/DataTable.js.map +1 -0
  169. package/dist/react/core/DataValue.d.ts +64 -0
  170. package/dist/react/core/DataValue.js +545 -0
  171. package/dist/react/core/DataValue.js.map +1 -0
  172. package/dist/react/core/Dialog.d.ts +32 -0
  173. package/dist/react/core/Dialog.js +201 -0
  174. package/dist/react/core/Dialog.js.map +1 -0
  175. package/dist/react/core/FileExplorer.d.ts +65 -0
  176. package/dist/react/core/FileExplorer.js +520 -0
  177. package/dist/react/core/FileExplorer.js.map +1 -0
  178. package/dist/react/core/GlassCard.d.ts +129 -0
  179. package/dist/react/core/GlassCard.js +375 -0
  180. package/dist/react/core/GlassCard.js.map +1 -0
  181. package/dist/react/core/HeaderIconWithStatus.d.ts +39 -0
  182. package/dist/react/core/HeaderIconWithStatus.js +157 -0
  183. package/dist/react/core/HeaderIconWithStatus.js.map +1 -0
  184. package/dist/react/core/HexViewer.d.ts +143 -0
  185. package/dist/react/core/HexViewer.js +1106 -0
  186. package/dist/react/core/HexViewer.js.map +1 -0
  187. package/dist/react/core/Icon.d.ts +32 -0
  188. package/dist/react/core/Icon.js +142 -0
  189. package/dist/react/core/Icon.js.map +1 -0
  190. package/dist/react/core/ImageGallery.d.ts +41 -0
  191. package/dist/react/core/ImageGallery.js +320 -0
  192. package/dist/react/core/ImageGallery.js.map +1 -0
  193. package/dist/react/core/Input.d.ts +38 -0
  194. package/dist/react/core/Input.js +288 -0
  195. package/dist/react/core/Input.js.map +1 -0
  196. package/dist/react/core/LimitsBar.d.ts +51 -0
  197. package/dist/react/core/LimitsBar.js +200 -0
  198. package/dist/react/core/LimitsBar.js.map +1 -0
  199. package/dist/react/core/LogViewer.d.ts +61 -0
  200. package/dist/react/core/LogViewer.js +599 -0
  201. package/dist/react/core/LogViewer.js.map +1 -0
  202. package/dist/react/core/MessageStream.d.ts +58 -0
  203. package/dist/react/core/MessageStream.js +455 -0
  204. package/dist/react/core/MessageStream.js.map +1 -0
  205. package/dist/react/core/MissionCalendar.d.ts +81 -0
  206. package/dist/react/core/MissionCalendar.js +1049 -0
  207. package/dist/react/core/MissionCalendar.js.map +1 -0
  208. package/dist/react/core/NumberInput.d.ts +85 -0
  209. package/dist/react/core/NumberInput.js +507 -0
  210. package/dist/react/core/NumberInput.js.map +1 -0
  211. package/dist/react/core/PacketViewer.d.ts +73 -0
  212. package/dist/react/core/PacketViewer.js +431 -0
  213. package/dist/react/core/PacketViewer.js.map +1 -0
  214. package/dist/react/core/Pagination.d.ts +30 -0
  215. package/dist/react/core/Pagination.js +190 -0
  216. package/dist/react/core/Pagination.js.map +1 -0
  217. package/dist/react/core/PinInput.d.ts +41 -0
  218. package/dist/react/core/PinInput.js +210 -0
  219. package/dist/react/core/PinInput.js.map +1 -0
  220. package/dist/react/core/Popover.d.ts +55 -0
  221. package/dist/react/core/Popover.js +288 -0
  222. package/dist/react/core/Popover.js.map +1 -0
  223. package/dist/react/core/Select.d.ts +42 -0
  224. package/dist/react/core/Select.js +303 -0
  225. package/dist/react/core/Select.js.map +1 -0
  226. package/dist/react/core/SideNav.d.ts +103 -0
  227. package/dist/react/core/SideNav.js +551 -0
  228. package/dist/react/core/SideNav.js.map +1 -0
  229. package/dist/react/core/SidePanel.d.ts +33 -0
  230. package/dist/react/core/SidePanel.js +199 -0
  231. package/dist/react/core/SidePanel.js.map +1 -0
  232. package/dist/react/core/Tabs.d.ts +47 -0
  233. package/dist/react/core/Tabs.js +129 -0
  234. package/dist/react/core/Tabs.js.map +1 -0
  235. package/dist/react/core/Toast.d.ts +56 -0
  236. package/dist/react/core/Toast.js +229 -0
  237. package/dist/react/core/Toast.js.map +1 -0
  238. package/dist/react/core/Toggle.d.ts +22 -0
  239. package/dist/react/core/Toggle.js +151 -0
  240. package/dist/react/core/Toggle.js.map +1 -0
  241. package/dist/react/core/Tooltip.d.ts +19 -0
  242. package/dist/react/core/Tooltip.js +179 -0
  243. package/dist/react/core/Tooltip.js.map +1 -0
  244. package/dist/react/core/Typography.d.ts +127 -0
  245. package/dist/react/core/Typography.js +187 -0
  246. package/dist/react/core/Typography.js.map +1 -0
  247. package/dist/react/core/index.d.ts +108 -0
  248. package/dist/react/core/layout/Box.d.ts +77 -0
  249. package/dist/react/core/layout/Box.js +126 -0
  250. package/dist/react/core/layout/Box.js.map +1 -0
  251. package/dist/react/core/layout/Center.d.ts +20 -0
  252. package/dist/react/core/layout/Center.js +34 -0
  253. package/dist/react/core/layout/Center.js.map +1 -0
  254. package/dist/react/core/layout/Divider.d.ts +16 -0
  255. package/dist/react/core/layout/Divider.js +108 -0
  256. package/dist/react/core/layout/Divider.js.map +1 -0
  257. package/dist/react/core/layout/Flex.d.ts +30 -0
  258. package/dist/react/core/layout/Flex.js +128 -0
  259. package/dist/react/core/layout/Flex.js.map +1 -0
  260. package/dist/react/core/layout/Grid.d.ts +36 -0
  261. package/dist/react/core/layout/Grid.js +142 -0
  262. package/dist/react/core/layout/Grid.js.map +1 -0
  263. package/dist/react/core/layout/Spacer.d.ts +8 -0
  264. package/dist/react/core/layout/Spacer.js +31 -0
  265. package/dist/react/core/layout/Spacer.js.map +1 -0
  266. package/dist/react/core/layout/Stack.d.ts +54 -0
  267. package/dist/react/core/layout/Stack.js +74 -0
  268. package/dist/react/core/layout/Stack.js.map +1 -0
  269. package/dist/react/core/layout/index.d.ts +38 -0
  270. package/dist/react/core/layout/responsive.d.ts +23 -0
  271. package/dist/react/core/layout/responsive.js +26 -0
  272. package/dist/react/core/layout/responsive.js.map +1 -0
  273. package/dist/react/core/layout/useBreakpoint.d.ts +77 -0
  274. package/dist/react/core/layout/useBreakpoint.js +73 -0
  275. package/dist/react/core/layout/useBreakpoint.js.map +1 -0
  276. package/dist/react/core/propertyConfig.d.ts +443 -0
  277. package/dist/react/core/propertyConfig.js +399 -0
  278. package/dist/react/core/propertyConfig.js.map +1 -0
  279. package/dist/react/hooks/index.d.ts +21 -0
  280. package/dist/react/hooks/useAccessWindows.d.ts +66 -0
  281. package/dist/react/hooks/useCompactMode.d.ts +82 -0
  282. package/dist/react/hooks/useCompactMode.js +62 -0
  283. package/dist/react/hooks/useCompactMode.js.map +1 -0
  284. package/dist/react/hooks/useLiveSelection.d.ts +57 -0
  285. package/dist/react/hooks/useSimulationPlayback.d.ts +97 -0
  286. package/dist/react/hooks/useSimulationTime.d.ts +61 -0
  287. package/dist/react/hooks/useSpacecraftPosition.d.ts +50 -0
  288. package/dist/react/hooks/useSpacecraftPosition.js +89 -0
  289. package/dist/react/hooks/useSpacecraftPosition.js.map +1 -0
  290. package/dist/react/hooks/useTelemetry.d.ts +55 -0
  291. package/dist/react/hooks/useTelemetry.js +73 -0
  292. package/dist/react/hooks/useTelemetry.js.map +1 -0
  293. package/dist/react/hooks/useZendirSession.d.ts +109 -0
  294. package/dist/react/hooks/useZendirSession.js +148 -0
  295. package/dist/react/hooks/useZendirSession.js.map +1 -0
  296. package/dist/react/index.d.ts +74 -0
  297. package/dist/react/shared/ErrorBoundary.d.ts +63 -0
  298. package/dist/react/shared/ErrorBoundary.js +142 -0
  299. package/dist/react/shared/ErrorBoundary.js.map +1 -0
  300. package/dist/react/shared/Skeleton.d.ts +110 -0
  301. package/dist/react/shared/Skeleton.js +324 -0
  302. package/dist/react/shared/Skeleton.js.map +1 -0
  303. package/dist/react/shared/index.d.ts +12 -0
  304. package/dist/react/theme/ThemeProvider.d.ts +385 -0
  305. package/dist/react/theme/ThemeProvider.js +1096 -0
  306. package/dist/react/theme/ThemeProvider.js.map +1 -0
  307. package/dist/react/theme/astro-tokens.d.ts +153 -0
  308. package/dist/react/theme/cardAccent.d.ts +75 -0
  309. package/dist/react/theme/cardAccent.js +137 -0
  310. package/dist/react/theme/cardAccent.js.map +1 -0
  311. package/dist/react/theme/config.d.ts +39 -0
  312. package/dist/react/theme/index.d.ts +9 -0
  313. package/dist/react/types.d.ts +360 -0
  314. package/dist/react/types.js +58 -0
  315. package/dist/react/types.js.map +1 -0
  316. package/dist/react/utils/index.d.ts +247 -0
  317. package/dist/react/utils/index.js +423 -0
  318. package/dist/react/utils/index.js.map +1 -0
  319. package/dist/react/visualizations/EclipseTimerCard.d.ts +17 -0
  320. package/dist/react/visualizations/EclipseTimerCard.js +250 -0
  321. package/dist/react/visualizations/EclipseTimerCard.js.map +1 -0
  322. package/dist/react/visualizations/LinkBudgetCard.d.ts +50 -0
  323. package/dist/react/visualizations/LinkBudgetCard.js +444 -0
  324. package/dist/react/visualizations/LinkBudgetCard.js.map +1 -0
  325. package/dist/react/visualizations/NavBallCard.d.ts +17 -0
  326. package/dist/react/visualizations/NavBallCard.js +243 -0
  327. package/dist/react/visualizations/NavBallCard.js.map +1 -0
  328. package/dist/react/visualizations/PropulsionCard.d.ts +37 -0
  329. package/dist/react/visualizations/PropulsionCard.js +298 -0
  330. package/dist/react/visualizations/PropulsionCard.js.map +1 -0
  331. package/dist/react/visualizations/SensorFootprintCard.d.ts +33 -0
  332. package/dist/react/visualizations/SensorFootprintCard.js +326 -0
  333. package/dist/react/visualizations/SensorFootprintCard.js.map +1 -0
  334. package/dist/react/visualizations/ThermalHeatmapCard.d.ts +38 -0
  335. package/dist/react/visualizations/ThermalHeatmapCard.js +372 -0
  336. package/dist/react/visualizations/ThermalHeatmapCard.js.map +1 -0
  337. package/dist/react/visualizations/index.d.ts +17 -0
  338. package/dist/react.d.ts +1 -0
  339. package/dist/react.js +421 -0
  340. package/dist/react.js.map +1 -0
  341. package/dist/shaders/atmosphere.frag.js +5 -0
  342. package/dist/shaders/atmosphere.frag.js.map +1 -0
  343. package/dist/shaders/atmosphere.vert.js +5 -0
  344. package/dist/shaders/atmosphere.vert.js.map +1 -0
  345. package/dist/shaders/stars.frag.js +5 -0
  346. package/dist/shaders/stars.frag.js.map +1 -0
  347. package/dist/shaders/stars.vert.js +5 -0
  348. package/dist/shaders/stars.vert.js.map +1 -0
  349. package/dist/style.css +143 -0
  350. package/dist/tokens/index.d.ts +296 -0
  351. package/dist/tokens/index.js +263 -0
  352. package/dist/tokens/index.js.map +1 -0
  353. package/dist/tokens/tokens.css +155 -0
  354. package/dist/types/index.d.ts +23 -0
  355. package/dist/types.d.ts +1 -0
  356. package/dist/types.js +2 -0
  357. package/dist/types.js.map +1 -0
  358. package/package.json +220 -0
  359. package/sdk-stub.js +22 -0
@@ -0,0 +1,61 @@
1
+ import { default as React } from 'react';
2
+
3
+ export type LogSeverity = 'debug' | 'info' | 'warn' | 'error' | 'critical';
4
+ export interface LogEntry {
5
+ /** Unique ID */
6
+ id: string | number;
7
+ /** Timestamp (ISO string or Date) */
8
+ timestamp: string | Date;
9
+ /** Severity level */
10
+ severity: LogSeverity;
11
+ /** Log message */
12
+ message: string;
13
+ /** Source component/system */
14
+ source?: string;
15
+ /** Additional metadata */
16
+ metadata?: Record<string, unknown>;
17
+ }
18
+ export interface LogViewerProps {
19
+ /** Array of log entries */
20
+ entries: LogEntry[];
21
+ /** Maximum entries to keep in memory (default: 5000). Older entries are pruned. */
22
+ maxEntries?: number;
23
+ /** Height of the viewer (default: 400) */
24
+ height?: number | string;
25
+ /** Title */
26
+ title?: string;
27
+ /** Show timestamps (default: true) */
28
+ showTimestamp?: boolean;
29
+ /** Show source column (default: true) */
30
+ showSource?: boolean;
31
+ /** Show severity filter toolbar (default: true) */
32
+ showFilters?: boolean;
33
+ /** Show search bar (default: true) */
34
+ showSearch?: boolean;
35
+ /** Initial severity filters (all enabled by default) */
36
+ defaultSeverities?: LogSeverity[];
37
+ /** Timestamp format: 'time', 'datetime', 'relative' (default: 'time') */
38
+ timestampFormat?: 'time' | 'datetime' | 'relative';
39
+ /** Called when an entry is clicked */
40
+ onEntryClick?: (entry: LogEntry) => void;
41
+ /** CSS class */
42
+ className?: string;
43
+ /** Show outer container border (default: true). Set false when embedded inside a Container/card. */
44
+ bordered?: boolean;
45
+ /** Custom style overrides for the outer container */
46
+ style?: React.CSSProperties;
47
+ /** Estimated row height in px for virtualization (default: 28). Enables smooth scroll through large logs. */
48
+ estimatedRowHeight?: number;
49
+ /** Number of rows to render above/below viewport for virtualization (default: 12). */
50
+ overscanCount?: number;
51
+ /**
52
+ * Enable pagination: show entries in pages with Previous/Next.
53
+ * Page 1 = newest entries. Use with large maxEntries so users can navigate to older pages.
54
+ * When set, scrolling is replaced by page navigation (better for very large logs).
55
+ */
56
+ pagination?: boolean | {
57
+ pageSize?: number;
58
+ };
59
+ }
60
+ export declare const LogViewer: React.NamedExoticComponent<LogViewerProps>;
61
+ export default LogViewer;
@@ -0,0 +1,599 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { memo, useRef, useState, useMemo, useEffect, useCallback } from "react";
3
+ import { useTheme } from "../theme/ThemeProvider.js";
4
+ const DEFAULT_ESTIMATED_ROW_HEIGHT = 28;
5
+ const DEFAULT_OVERSCAN_COUNT = 12;
6
+ const SEVERITY_ORDER = ["debug", "info", "warn", "error", "critical"];
7
+ function formatTimestamp(ts, format) {
8
+ const d = typeof ts === "string" ? new Date(ts) : ts;
9
+ if (isNaN(d.getTime())) return String(ts);
10
+ if (format === "time") {
11
+ return d.toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" }) + "." + d.getMilliseconds().toString().padStart(3, "0");
12
+ }
13
+ if (format === "datetime") {
14
+ return d.toLocaleDateString("en-US", { month: "short", day: "2-digit" }) + " " + d.toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" });
15
+ }
16
+ const diff = Date.now() - d.getTime();
17
+ if (diff < 1e3) return "just now";
18
+ if (diff < 6e4) return `${Math.floor(diff / 1e3)}s ago`;
19
+ if (diff < 36e5) return `${Math.floor(diff / 6e4)}m ago`;
20
+ return `${Math.floor(diff / 36e5)}h ago`;
21
+ }
22
+ const LogViewer = memo(function LogViewer2({
23
+ entries,
24
+ maxEntries = 5e3,
25
+ height = 400,
26
+ title,
27
+ showTimestamp = true,
28
+ showSource = true,
29
+ showFilters = true,
30
+ showSearch = true,
31
+ defaultSeverities,
32
+ timestampFormat = "time",
33
+ onEntryClick,
34
+ className = "",
35
+ bordered = true,
36
+ style: styleProp,
37
+ estimatedRowHeight = DEFAULT_ESTIMATED_ROW_HEIGHT,
38
+ overscanCount = DEFAULT_OVERSCAN_COUNT,
39
+ pagination
40
+ }) {
41
+ const { tokens, theme } = useTheme();
42
+ const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
43
+ const scrollRef = useRef(null);
44
+ const [paused, setPaused] = useState(false);
45
+ const [searchQuery, setSearchQuery] = useState("");
46
+ const [severityFilter, setSeverityFilter] = useState(
47
+ new Set(defaultSeverities ?? SEVERITY_ORDER)
48
+ );
49
+ const [autoScroll, setAutoScroll] = useState(true);
50
+ const prevLengthRef = useRef(entries.length);
51
+ const [scrollState, setScrollState] = useState({ scrollTop: 0, containerHeight: 300 });
52
+ const rafRef = useRef(null);
53
+ const severityColors = {
54
+ debug: tokens.colors.text.muted ?? tokens.colors.text.secondary,
55
+ info: tokens.colors.status.standby,
56
+ warn: tokens.colors.status.caution,
57
+ error: tokens.colors.status.serious,
58
+ critical: tokens.colors.status.critical
59
+ };
60
+ const severityShapes = {
61
+ debug: "·",
62
+ info: "○",
63
+ warn: "■",
64
+ error: "◆",
65
+ critical: "▼"
66
+ };
67
+ const severityLabels = {
68
+ debug: "DBG",
69
+ info: "INF",
70
+ warn: "WRN",
71
+ error: "ERR",
72
+ critical: "CRT"
73
+ };
74
+ const filteredEntries = useMemo(() => {
75
+ let filtered = entries.filter((e) => severityFilter.has(e.severity));
76
+ if (searchQuery.trim()) {
77
+ const q = searchQuery.toLowerCase();
78
+ filtered = filtered.filter(
79
+ (e) => e.message.toLowerCase().includes(q) || e.source && e.source.toLowerCase().includes(q)
80
+ );
81
+ }
82
+ return filtered.slice(0, maxEntries);
83
+ }, [entries, severityFilter, searchQuery, maxEntries]);
84
+ const paginationConfig = pagination === true ? { pageSize: 200 } : pagination || void 0;
85
+ const pageSize = (paginationConfig == null ? void 0 : paginationConfig.pageSize) ?? 200;
86
+ const totalPages = Math.max(1, Math.ceil(filteredEntries.length / pageSize));
87
+ const [currentPage, setCurrentPage] = useState(1);
88
+ useEffect(() => {
89
+ setCurrentPage((p) => Math.min(p, totalPages));
90
+ }, [totalPages]);
91
+ const paginationEntries = useMemo(() => {
92
+ if (!paginationConfig) return null;
93
+ const start = (currentPage - 1) * pageSize;
94
+ return filteredEntries.slice(start, start + pageSize);
95
+ }, [paginationConfig, currentPage, pageSize, filteredEntries]);
96
+ const totalHeight = filteredEntries.length * estimatedRowHeight;
97
+ const { scrollTop, containerHeight } = scrollState;
98
+ const visibleRange = useMemo(() => {
99
+ const start = Math.max(0, Math.floor(scrollTop / estimatedRowHeight) - overscanCount);
100
+ const end = Math.min(
101
+ filteredEntries.length,
102
+ Math.ceil((scrollTop + containerHeight) / estimatedRowHeight) + overscanCount
103
+ );
104
+ return { start, end };
105
+ }, [scrollTop, containerHeight, estimatedRowHeight, overscanCount, filteredEntries.length]);
106
+ const visibleEntries = useMemo(
107
+ () => filteredEntries.slice(visibleRange.start, visibleRange.end),
108
+ [filteredEntries, visibleRange.start, visibleRange.end]
109
+ );
110
+ const usePagination = !!paginationConfig;
111
+ const renderRow = useCallback((entry) => /* @__PURE__ */ jsxs(
112
+ "div",
113
+ {
114
+ role: onEntryClick ? "button" : "listitem",
115
+ tabIndex: onEntryClick ? 0 : void 0,
116
+ "aria-label": onEntryClick ? `${severityLabels[entry.severity]}: ${entry.message}` : void 0,
117
+ onClick: () => onEntryClick == null ? void 0 : onEntryClick(entry),
118
+ onKeyDown: onEntryClick ? (e) => (e.key === "Enter" || e.key === " ") && (e.preventDefault(), onEntryClick(entry)) : void 0,
119
+ style: {
120
+ display: "flex",
121
+ alignItems: "flex-start",
122
+ minHeight: estimatedRowHeight,
123
+ boxSizing: "border-box",
124
+ padding: "3px 12px",
125
+ borderBottom: `1px solid ${tokens.colors.border.muted}11`,
126
+ cursor: onEntryClick ? "pointer" : "default",
127
+ transition: "background 150ms ease"
128
+ },
129
+ onMouseEnter: (e) => {
130
+ e.currentTarget.style.background = `${tokens.colors.background.surface}`;
131
+ },
132
+ onMouseLeave: (e) => {
133
+ e.currentTarget.style.background = "transparent";
134
+ },
135
+ children: [
136
+ /* @__PURE__ */ jsxs("span", { style: {
137
+ color: severityColors[entry.severity],
138
+ fontWeight: 700,
139
+ fontSize: tokens.typography.fontSize.xxs,
140
+ minWidth: 38,
141
+ textAlign: "center",
142
+ background: `${severityColors[entry.severity]}18`,
143
+ borderRadius: tokens.borderRadius.sm,
144
+ padding: "1px 4px",
145
+ marginRight: 8,
146
+ marginTop: 1,
147
+ letterSpacing: "0.3px",
148
+ display: "inline-flex",
149
+ alignItems: "center",
150
+ justifyContent: "center",
151
+ gap: 3
152
+ }, children: [
153
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "8px", lineHeight: 1 }, children: severityShapes[entry.severity] }),
154
+ severityLabels[entry.severity]
155
+ ] }),
156
+ showTimestamp && /* @__PURE__ */ jsx("span", { style: {
157
+ color: tokens.colors.text.muted,
158
+ marginRight: 8,
159
+ minWidth: 85,
160
+ fontSize: 11,
161
+ flexShrink: 0
162
+ }, children: formatTimestamp(entry.timestamp, timestampFormat) }),
163
+ showSource && entry.source && /* @__PURE__ */ jsxs("span", { style: {
164
+ color: tokens.colors.interactive.default,
165
+ marginRight: 8,
166
+ fontSize: 11,
167
+ minWidth: 70,
168
+ maxWidth: 100,
169
+ overflow: "hidden",
170
+ textOverflow: "ellipsis",
171
+ whiteSpace: "nowrap",
172
+ flexShrink: 0
173
+ }, children: [
174
+ "[",
175
+ entry.source,
176
+ "]"
177
+ ] }),
178
+ /* @__PURE__ */ jsx("span", { style: {
179
+ color: entry.severity === "error" || entry.severity === "critical" ? severityColors[entry.severity] : tokens.colors.text.primary,
180
+ flex: 1,
181
+ wordBreak: "break-word",
182
+ lineHeight: 1.4
183
+ }, children: entry.message })
184
+ ]
185
+ },
186
+ entry.id
187
+ ), [severityColors, severityShapes, severityLabels, estimatedRowHeight, tokens, showTimestamp, showSource, timestampFormat, onEntryClick]);
188
+ useEffect(() => {
189
+ const el = scrollRef.current;
190
+ if (!el) return;
191
+ const ro = new ResizeObserver(() => {
192
+ setScrollState((s) => ({ ...s, containerHeight: el.clientHeight }));
193
+ });
194
+ ro.observe(el);
195
+ setScrollState((s) => ({ ...s, containerHeight: el.clientHeight }));
196
+ return () => ro.disconnect();
197
+ }, []);
198
+ const handleScroll = useCallback(() => {
199
+ const el = scrollRef.current;
200
+ if (!el) return;
201
+ const { scrollTop: st, scrollHeight, clientHeight } = el;
202
+ const atBottom = scrollHeight - st - clientHeight < 30;
203
+ setAutoScroll(atBottom);
204
+ if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);
205
+ rafRef.current = requestAnimationFrame(() => {
206
+ rafRef.current = null;
207
+ setScrollState((prev) => ({ ...prev, scrollTop: el.scrollTop }));
208
+ });
209
+ }, []);
210
+ useEffect(() => {
211
+ if (entries.length <= prevLengthRef.current) {
212
+ prevLengthRef.current = entries.length;
213
+ return;
214
+ }
215
+ if (!usePagination && !paused && autoScroll && scrollRef.current) {
216
+ scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
217
+ }
218
+ prevLengthRef.current = entries.length;
219
+ }, [entries.length, paused, autoScroll, usePagination]);
220
+ useEffect(() => () => {
221
+ if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);
222
+ }, []);
223
+ const toggleSeverity = useCallback((sev) => {
224
+ setSeverityFilter((prev) => {
225
+ const next = new Set(prev);
226
+ if (next.has(sev)) next.delete(sev);
227
+ else next.add(sev);
228
+ return next;
229
+ });
230
+ }, []);
231
+ const exportLog = useCallback(() => {
232
+ var _a;
233
+ const text = filteredEntries.map((e) => {
234
+ const ts = formatTimestamp(e.timestamp, "datetime");
235
+ const src = e.source ? `[${e.source}]` : "";
236
+ return `${ts} [${e.severity.toUpperCase()}] ${src} ${e.message}`;
237
+ }).join("\n");
238
+ (_a = navigator.clipboard) == null ? void 0 : _a.writeText(text);
239
+ }, [filteredEntries]);
240
+ const clearFilters = useCallback(() => {
241
+ setSeverityFilter(new Set(SEVERITY_ORDER));
242
+ setSearchQuery("");
243
+ }, []);
244
+ const counts = useMemo(() => {
245
+ const c = { debug: 0, info: 0, warn: 0, error: 0, critical: 0 };
246
+ entries.forEach((e) => {
247
+ c[e.severity]++;
248
+ });
249
+ return c;
250
+ }, [entries]);
251
+ return /* @__PURE__ */ jsxs(
252
+ "div",
253
+ {
254
+ className: `log-viewer ${className}`,
255
+ style: {
256
+ height: typeof height === "number" ? `${height}px` : height,
257
+ minHeight: typeof height === "number" ? `${height}px` : height,
258
+ background: tokens.colors.background.base,
259
+ ...bordered ? tokens.colors.border.cardStyle ?? { border: `1px solid ${tokens.colors.border.muted}` } : { border: "none" },
260
+ borderRadius: tokens.borderRadius.lg,
261
+ overflow: "hidden",
262
+ display: "flex",
263
+ flexDirection: "column",
264
+ fontFamily: tokens.typography.fontFamily.mono,
265
+ ...styleProp,
266
+ fontSize: tokens.typography.fontSize.xs,
267
+ color: tokens.colors.text.primary,
268
+ backdropFilter: isTransparentTheme ? "blur(10px)" : void 0,
269
+ WebkitBackdropFilter: isTransparentTheme ? "blur(10px)" : void 0
270
+ },
271
+ children: [
272
+ title && /* @__PURE__ */ jsxs("div", { style: {
273
+ padding: "8px 12px",
274
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
275
+ display: "flex",
276
+ alignItems: "center",
277
+ justifyContent: "space-between",
278
+ background: tokens.colors.background.surface,
279
+ fontFamily: tokens.typography.fontFamily.primary,
280
+ backdropFilter: "blur(8px)"
281
+ }, children: [
282
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, fontSize: 13 }, children: title }),
283
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: /* @__PURE__ */ jsxs("span", { style: { fontSize: 11, color: tokens.colors.text.muted }, children: [
284
+ filteredEntries.length.toLocaleString(),
285
+ " entries"
286
+ ] }) })
287
+ ] }),
288
+ (showFilters || showSearch) && /* @__PURE__ */ jsxs("div", { style: {
289
+ padding: "6px 12px",
290
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
291
+ display: "flex",
292
+ alignItems: "center",
293
+ gap: 8,
294
+ flexWrap: "wrap",
295
+ background: tokens.colors.background.surface,
296
+ fontFamily: tokens.typography.fontFamily.primary
297
+ }, children: [
298
+ showFilters && SEVERITY_ORDER.map((sev) => /* @__PURE__ */ jsxs(
299
+ "button",
300
+ {
301
+ onClick: () => toggleSeverity(sev),
302
+ "aria-pressed": severityFilter.has(sev),
303
+ "aria-label": `Filter ${sev} logs (${counts[sev]})`,
304
+ style: {
305
+ background: severityFilter.has(sev) ? `${severityColors[sev]}22` : "transparent",
306
+ color: severityFilter.has(sev) ? severityColors[sev] : tokens.colors.text.muted,
307
+ border: `1px solid ${severityFilter.has(sev) ? severityColors[sev] + "66" : tokens.colors.border.muted}`,
308
+ borderRadius: tokens.borderRadius.md,
309
+ padding: `${tokens.spacing.xxs} ${tokens.spacing.sm}`,
310
+ fontSize: tokens.typography.fontSize.xxs,
311
+ fontWeight: tokens.typography.fontWeight.medium,
312
+ cursor: "pointer",
313
+ textTransform: "uppercase",
314
+ letterSpacing: "0.5px",
315
+ transition: "all 150ms ease"
316
+ },
317
+ children: [
318
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: severityShapes[sev] }),
319
+ " ",
320
+ sev,
321
+ " (",
322
+ counts[sev],
323
+ ")"
324
+ ]
325
+ },
326
+ sev
327
+ )),
328
+ /* @__PURE__ */ jsx("div", { style: { flex: 1 } }),
329
+ showSearch && /* @__PURE__ */ jsx(
330
+ "input",
331
+ {
332
+ type: "text",
333
+ value: searchQuery,
334
+ onChange: (e) => setSearchQuery(e.target.value),
335
+ placeholder: "Filter messages...",
336
+ "aria-label": "Filter log messages",
337
+ style: {
338
+ background: tokens.colors.background.base,
339
+ color: tokens.colors.text.primary,
340
+ border: `1px solid ${tokens.colors.border.muted}`,
341
+ borderRadius: tokens.borderRadius.md,
342
+ padding: `3px ${tokens.spacing.sm}`,
343
+ fontSize: tokens.typography.fontSize.sm,
344
+ outline: "none",
345
+ minWidth: 150
346
+ }
347
+ }
348
+ ),
349
+ /* @__PURE__ */ jsx(
350
+ "button",
351
+ {
352
+ onClick: () => setPaused((p) => !p),
353
+ "aria-label": paused ? "Resume log stream" : "Pause log stream",
354
+ style: {
355
+ background: paused ? `${tokens.colors.status.caution}22` : tokens.colors.background.base,
356
+ color: paused ? tokens.colors.status.caution : tokens.colors.text.secondary,
357
+ border: `1px solid ${tokens.colors.border.muted}`,
358
+ borderRadius: tokens.borderRadius.md,
359
+ padding: `${tokens.spacing.xxs} ${tokens.spacing.sm}`,
360
+ fontSize: tokens.typography.fontSize.xxs,
361
+ cursor: "pointer",
362
+ fontWeight: tokens.typography.fontWeight.medium,
363
+ transition: "all 150ms ease"
364
+ },
365
+ children: paused ? "▶ Resume" : "⏸ Pause"
366
+ }
367
+ ),
368
+ /* @__PURE__ */ jsx("button", { onClick: exportLog, "aria-label": "Copy log to clipboard", style: {
369
+ background: tokens.colors.background.base,
370
+ color: tokens.colors.text.secondary,
371
+ border: `1px solid ${tokens.colors.border.muted}`,
372
+ borderRadius: tokens.borderRadius.md,
373
+ padding: `${tokens.spacing.xxs} ${tokens.spacing.sm}`,
374
+ fontSize: tokens.typography.fontSize.xxs,
375
+ cursor: "pointer",
376
+ transition: "all 150ms ease"
377
+ }, children: "Copy" }),
378
+ /* @__PURE__ */ jsx("button", { onClick: clearFilters, "aria-label": "Reset all filters", style: {
379
+ background: tokens.colors.background.base,
380
+ color: tokens.colors.text.secondary,
381
+ border: `1px solid ${tokens.colors.border.muted}`,
382
+ borderRadius: tokens.borderRadius.md,
383
+ padding: `${tokens.spacing.xxs} ${tokens.spacing.sm}`,
384
+ fontSize: tokens.typography.fontSize.xxs,
385
+ cursor: "pointer",
386
+ transition: "all 150ms ease"
387
+ }, children: "Reset" })
388
+ ] }),
389
+ /* @__PURE__ */ jsx(
390
+ "div",
391
+ {
392
+ ref: scrollRef,
393
+ onScroll: handleScroll,
394
+ className: "zendir-log-scroll",
395
+ style: {
396
+ flex: 1,
397
+ minHeight: 0,
398
+ overflowY: "auto",
399
+ overflowX: "hidden",
400
+ padding: "2px 0",
401
+ overscrollBehavior: "contain",
402
+ WebkitOverflowScrolling: "touch"
403
+ },
404
+ children: filteredEntries.length === 0 ? /* @__PURE__ */ jsx("div", { style: {
405
+ display: "flex",
406
+ alignItems: "center",
407
+ justifyContent: "center",
408
+ height: "100%",
409
+ color: tokens.colors.text.muted,
410
+ fontSize: 13,
411
+ fontFamily: tokens.typography.fontFamily.primary
412
+ }, children: entries.length === 0 ? "No log entries" : "No matching entries" }) : usePagination ? /* @__PURE__ */ jsx("div", { style: { padding: "2px 0" }, role: "list", "aria-label": "Log entries", children: (paginationEntries ?? []).map((entry) => renderRow(entry)) }) : /* @__PURE__ */ jsxs(
413
+ "div",
414
+ {
415
+ style: {
416
+ height: totalHeight,
417
+ position: "relative",
418
+ width: "100%"
419
+ },
420
+ role: "list",
421
+ "aria-label": "Log entries",
422
+ children: [
423
+ visibleRange.start > 0 && /* @__PURE__ */ jsx(
424
+ "div",
425
+ {
426
+ style: { height: visibleRange.start * estimatedRowHeight, width: "100%" },
427
+ "aria-hidden": true
428
+ }
429
+ ),
430
+ visibleEntries.map((entry) => renderRow(entry)),
431
+ visibleRange.end < filteredEntries.length && /* @__PURE__ */ jsx(
432
+ "div",
433
+ {
434
+ style: {
435
+ height: (filteredEntries.length - visibleRange.end) * estimatedRowHeight,
436
+ width: "100%"
437
+ },
438
+ "aria-hidden": true
439
+ }
440
+ )
441
+ ]
442
+ }
443
+ )
444
+ }
445
+ ),
446
+ usePagination && filteredEntries.length > 0 && /* @__PURE__ */ jsxs(
447
+ "div",
448
+ {
449
+ style: {
450
+ display: "flex",
451
+ alignItems: "center",
452
+ justifyContent: "space-between",
453
+ flexWrap: "wrap",
454
+ gap: tokens.spacing.sm,
455
+ padding: `${tokens.spacing.xs} ${tokens.spacing.smd}`,
456
+ borderTop: `1px solid ${tokens.colors.border.muted}`,
457
+ background: tokens.colors.background.surface,
458
+ fontFamily: tokens.typography.fontFamily.primary,
459
+ fontSize: tokens.typography.fontSize.xs,
460
+ color: tokens.colors.text.secondary
461
+ },
462
+ children: [
463
+ /* @__PURE__ */ jsxs("span", { "aria-live": "polite", children: [
464
+ "Page ",
465
+ currentPage,
466
+ " of ",
467
+ totalPages,
468
+ filteredEntries.length > 0 && /* @__PURE__ */ jsxs("span", { style: { marginLeft: tokens.spacing.sm }, children: [
469
+ "(",
470
+ ((currentPage - 1) * pageSize + 1).toLocaleString(),
471
+ "–",
472
+ Math.min(currentPage * pageSize, filteredEntries.length).toLocaleString(),
473
+ " of ",
474
+ filteredEntries.length.toLocaleString(),
475
+ ")"
476
+ ] })
477
+ ] }),
478
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.xs }, children: [
479
+ /* @__PURE__ */ jsx(
480
+ "button",
481
+ {
482
+ type: "button",
483
+ onClick: () => {
484
+ setCurrentPage(1);
485
+ setAutoScroll(true);
486
+ },
487
+ disabled: currentPage <= 1,
488
+ "aria-label": "First page (newest)",
489
+ style: {
490
+ padding: `${tokens.spacing.xxs} ${tokens.spacing.sm}`,
491
+ border: `1px solid ${tokens.colors.border.muted}`,
492
+ borderRadius: tokens.borderRadius.md,
493
+ background: tokens.colors.background.base,
494
+ color: tokens.colors.text.primary,
495
+ fontSize: tokens.typography.fontSize.xxs,
496
+ cursor: currentPage <= 1 ? "not-allowed" : "pointer",
497
+ opacity: currentPage <= 1 ? 0.5 : 1
498
+ },
499
+ children: "First"
500
+ }
501
+ ),
502
+ /* @__PURE__ */ jsx(
503
+ "button",
504
+ {
505
+ type: "button",
506
+ onClick: () => {
507
+ setCurrentPage((p) => Math.max(1, p - 1));
508
+ setAutoScroll(false);
509
+ },
510
+ disabled: currentPage <= 1,
511
+ "aria-label": "Previous page",
512
+ style: {
513
+ padding: `${tokens.spacing.xxs} ${tokens.spacing.sm}`,
514
+ border: `1px solid ${tokens.colors.border.muted}`,
515
+ borderRadius: tokens.borderRadius.md,
516
+ background: tokens.colors.background.base,
517
+ color: tokens.colors.text.primary,
518
+ fontSize: tokens.typography.fontSize.xxs,
519
+ cursor: currentPage <= 1 ? "not-allowed" : "pointer",
520
+ opacity: currentPage <= 1 ? 0.5 : 1
521
+ },
522
+ children: "Previous"
523
+ }
524
+ ),
525
+ /* @__PURE__ */ jsx(
526
+ "button",
527
+ {
528
+ type: "button",
529
+ onClick: () => {
530
+ setCurrentPage((p) => Math.min(totalPages, p + 1));
531
+ setAutoScroll(false);
532
+ },
533
+ disabled: currentPage >= totalPages,
534
+ "aria-label": "Next page",
535
+ style: {
536
+ padding: `${tokens.spacing.xxs} ${tokens.spacing.sm}`,
537
+ border: `1px solid ${tokens.colors.border.muted}`,
538
+ borderRadius: tokens.borderRadius.md,
539
+ background: tokens.colors.background.base,
540
+ color: tokens.colors.text.primary,
541
+ fontSize: tokens.typography.fontSize.xxs,
542
+ cursor: currentPage >= totalPages ? "not-allowed" : "pointer",
543
+ opacity: currentPage >= totalPages ? 0.5 : 1
544
+ },
545
+ children: "Next"
546
+ }
547
+ ),
548
+ /* @__PURE__ */ jsx(
549
+ "button",
550
+ {
551
+ type: "button",
552
+ onClick: () => {
553
+ setCurrentPage(totalPages);
554
+ setAutoScroll(false);
555
+ },
556
+ disabled: currentPage >= totalPages,
557
+ "aria-label": "Last page (oldest)",
558
+ style: {
559
+ padding: `${tokens.spacing.xxs} ${tokens.spacing.sm}`,
560
+ border: `1px solid ${tokens.colors.border.muted}`,
561
+ borderRadius: tokens.borderRadius.md,
562
+ background: tokens.colors.background.base,
563
+ color: tokens.colors.text.primary,
564
+ fontSize: tokens.typography.fontSize.xxs,
565
+ cursor: currentPage >= totalPages ? "not-allowed" : "pointer",
566
+ opacity: currentPage >= totalPages ? 0.5 : 1
567
+ },
568
+ children: "Last"
569
+ }
570
+ )
571
+ ] })
572
+ ]
573
+ }
574
+ ),
575
+ /* @__PURE__ */ jsx("style", { children: `
576
+ .zendir-log-scroll::-webkit-scrollbar { width: 6px; }
577
+ .zendir-log-scroll::-webkit-scrollbar-track { background: transparent; }
578
+ .zendir-log-scroll::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 3px; }
579
+ .zendir-log-scroll::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.25); }
580
+ .zendir-log-scroll { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,0.15) transparent; }
581
+ ` }),
582
+ paused && /* @__PURE__ */ jsx("div", { role: "status", style: {
583
+ padding: `${tokens.spacing.xs} ${tokens.spacing.smd}`,
584
+ borderTop: `1px solid ${tokens.colors.border.muted}`,
585
+ background: `${tokens.colors.status.caution}15`,
586
+ color: tokens.colors.status.caution,
587
+ fontSize: tokens.typography.fontSize.sm,
588
+ textAlign: "center",
589
+ fontFamily: tokens.typography.fontFamily.primary,
590
+ fontWeight: tokens.typography.fontWeight.medium
591
+ }, children: "Log paused — new entries are buffered" })
592
+ ]
593
+ }
594
+ );
595
+ });
596
+ export {
597
+ LogViewer
598
+ };
599
+ //# sourceMappingURL=LogViewer.js.map