diff --git a/webui/bun.lockb b/webui/bun.lockb index e11c602..97e6b19 100755 Binary files a/webui/bun.lockb and b/webui/bun.lockb differ diff --git a/webui/package.json b/webui/package.json index de00117..2686332 100644 --- a/webui/package.json +++ b/webui/package.json @@ -21,6 +21,7 @@ "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-toast": "^1.1.5", + "@radix-ui/react-tooltip": "^1.1.2", "@tailwindcss/typography": "^0.5.10", "@tanstack/react-query": "^5.22.2", "class-variance-authority": "^0.7.0", diff --git a/webui/src/app/(atlas)/[bundle].tsx b/webui/src/app/(atlas)/[bundle].tsx index 0e6e3c3..dc0f290 100644 --- a/webui/src/app/(atlas)/[bundle].tsx +++ b/webui/src/app/(atlas)/[bundle].tsx @@ -3,6 +3,7 @@ import { keepPreviousData, useQuery } from '@tanstack/react-query'; import type { ModuleGraphResponse } from '~/app/--/bundles/[bundle]/modules/graph+api'; import { BundleGraph } from '~/components/BundleGraph'; import { BundleSelectForm } from '~/components/BundleSelectForm'; +import { FileSize } from '~/components/FileSize'; import { ModuleFiltersForm } from '~/components/ModuleFilterForm'; import { PropertySummary } from '~/components/PropertySummary'; import { @@ -17,7 +18,6 @@ import { Layout, LayoutHeader, LayoutNavigation, LayoutTitle } from '~/ui/Layout import { Tag } from '~/ui/Tag'; import { fetchApi, handleApiError } from '~/utils/api'; import { type ModuleFilters, moduleFiltersToParams } from '~/utils/filters'; -import { formatFileSize } from '~/utils/formatString'; export default function BundlePage() { const { bundle } = useBundle(); @@ -40,14 +40,14 @@ export default function BundlePage() { {!!modules.data && {modules.data.bundle.moduleFiles} modules} - {!!modules.data && {formatFileSize(modules.data.bundle.moduleSize)}} + {!!modules.data && } {!!modules.data && modulesAreFiltered && ( visible:} > {modules.data.filtered.moduleFiles} modules - {formatFileSize(modules.data.filtered.moduleSize)} + )} diff --git a/webui/src/app/(atlas)/[bundle]/folders/[path].tsx b/webui/src/app/(atlas)/[bundle]/folders/[path].tsx index 9da9ea3..04e1440 100644 --- a/webui/src/app/(atlas)/[bundle]/folders/[path].tsx +++ b/webui/src/app/(atlas)/[bundle]/folders/[path].tsx @@ -5,6 +5,7 @@ import type { ModuleGraphResponse } from '~/app/--/bundles/[bundle]/modules/grap import { BreadcrumbLinks } from '~/components/BreadcrumbLinks'; import { BundleGraph } from '~/components/BundleGraph'; import { BundleSelectForm } from '~/components/BundleSelectForm'; +import { FileSize } from '~/components/FileSize'; import { ModuleFiltersForm } from '~/components/ModuleFilterForm'; import { PropertySummary } from '~/components/PropertySummary'; import { @@ -19,7 +20,6 @@ import { Layout, LayoutHeader, LayoutNavigation, LayoutTitle } from '~/ui/Layout import { Tag } from '~/ui/Tag'; import { fetchApi, handleApiError } from '~/utils/api'; import { type ModuleFilters, moduleFiltersToParams } from '~/utils/filters'; -import { formatFileSize } from '~/utils/formatString'; export default function FolderPage() { const { path: relativePath } = useLocalSearchParams<{ path: string }>(); @@ -47,7 +47,7 @@ export default function FolderPage() { )} {!!modules.data?.filtered.moduleSize && ( - {formatFileSize(modules.data.filtered.moduleSize)} + )} diff --git a/webui/src/app/(atlas)/[bundle]/modules/[path].tsx b/webui/src/app/(atlas)/[bundle]/modules/[path].tsx index 4003d9e..e0c50c0 100644 --- a/webui/src/app/(atlas)/[bundle]/modules/[path].tsx +++ b/webui/src/app/(atlas)/[bundle]/modules/[path].tsx @@ -3,6 +3,7 @@ import { useLocalSearchParams } from 'expo-router'; import { BreadcrumbLinks } from '~/components/BreadcrumbLinks'; import { BundleSelectForm } from '~/components/BundleSelectForm'; +import { FileSize } from '~/components/FileSize'; import { ModuleCode } from '~/components/ModuleCode'; import { ModuleReference } from '~/components/ModuleReference'; import { PropertySummary } from '~/components/PropertySummary'; @@ -12,7 +13,6 @@ import { Layout, LayoutHeader, LayoutNavigation, LayoutTitle } from '~/ui/Layout import { Skeleton } from '~/ui/Skeleton'; import { Tag } from '~/ui/Tag'; import { fetchApi, handleApiError } from '~/utils/api'; -import { formatFileSize } from '~/utils/formatString'; import { type AtlasModule } from '~core/data/types'; export default function ModulePage() { @@ -32,7 +32,7 @@ export default function ModulePage() { {!!module.data?.package && {module.data.package}} {!!module.data && {getModuleType(module.data)}} - {!!module.data && {formatFileSize(module.data.size)}} + {!!module.data && } diff --git a/webui/src/components/BundleGraph.tsx b/webui/src/components/BundleGraph.tsx index 3560533..4fdc2e9 100644 --- a/webui/src/components/BundleGraph.tsx +++ b/webui/src/components/BundleGraph.tsx @@ -8,7 +8,7 @@ import EchartsReact from 'echarts-for-react/lib/core'; import { useRouter } from 'expo-router'; import { useMemo } from 'react'; -import { formatFileSize } from '~/utils/formatString'; +import { formatByteSize } from '~/components/FileSize'; import type { TreemapNode } from '~/utils/treemap'; import type { PartialAtlasBundle } from '~core/data/types'; @@ -195,7 +195,7 @@ function getBundleGraphTooltip( ${formatNodeValue(node)}
- Size: ${formatFileSize(size)} + Size: ${formatByteSize(size)} ${ files === 1 ? `Files: ${files}` diff --git a/webui/src/components/FileSize.tsx b/webui/src/components/FileSize.tsx new file mode 100644 index 0000000..e95d581 --- /dev/null +++ b/webui/src/components/FileSize.tsx @@ -0,0 +1,54 @@ +// @ts-expect-error +import AsteriskIcon from 'lucide-react/dist/esm/icons/asterisk'; + +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '~/ui/Tooltip'; + +type BundleFileSizeProps = { + /** The size of the files or bundle, in bytes */ + byteSize: number; +}; + +export function FileSize(props: BundleFileSizeProps) { + return ( +
+ {formatByteSize(props.byteSize)} + + + + + + +

+ All file sizes are calculated based on the transpiled JavaScript byte size. +

+

+ While these sizes might differ from actual bundle size when using{' '} + + Hermes Bytecode (HBC) + + , the relative proportions are still correct. +

+
+
+
+
+ ); +} + +/** Format files or bundle size, from bytes to the nearest unit */ +export function formatByteSize(size: number) { + if (size < 1024) { + return size + 'B'; + } else if (size < 1024 * 1024) { + return (size / 1024).toFixed(1) + 'KB'; + } else { + return (size / 1024 / 1024).toFixed(1) + 'MB'; + } +} diff --git a/webui/src/ui/Tooltip.tsx b/webui/src/ui/Tooltip.tsx new file mode 100644 index 0000000..9daff07 --- /dev/null +++ b/webui/src/ui/Tooltip.tsx @@ -0,0 +1,30 @@ +// see: https://ui.shadcn.com/docs/components/tooltip + +import * as TooltipPrimitive from '@radix-ui/react-tooltip'; +import { cx } from 'class-variance-authority'; +import { type ComponentPropsWithoutRef, type ElementRef, forwardRef } from 'react'; + +export const TooltipProvider = TooltipPrimitive.Provider; + +export const Tooltip = TooltipPrimitive.Root; + +export const TooltipTrigger = TooltipPrimitive.Trigger; + +export const TooltipContent = forwardRef< + ElementRef, + ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + +)); + +TooltipContent.displayName = TooltipPrimitive.Content.displayName; diff --git a/webui/src/utils/formatString.ts b/webui/src/utils/formatString.ts deleted file mode 100644 index a54bbd1..0000000 --- a/webui/src/utils/formatString.ts +++ /dev/null @@ -1,9 +0,0 @@ -export function formatFileSize(size: number) { - if (size < 1024) { - return size + 'B'; - } else if (size < 1024 * 1024) { - return (size / 1024).toFixed(1) + 'KB'; - } else { - return (size / 1024 / 1024).toFixed(1) + 'MB'; - } -}