diff --git a/app/src/analytics/reportWebVitals.test.ts b/app/src/analytics/reportWebVitals.test.ts index 5c17818d68..ed65360836 100644 --- a/app/src/analytics/reportWebVitals.test.ts +++ b/app/src/analytics/reportWebVitals.test.ts @@ -1,7 +1,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest'; -import { setAnalyticsAmbientProps } from '../hooks/useAnalytics'; -import { reportWebVitals } from './reportWebVitals'; +import { reportWebVitals } from 'src/analytics/reportWebVitals'; +import { setAnalyticsAmbientProps } from 'src/hooks/useAnalytics'; // Single hoisted mock (vi.mock dedupes by module path — last call wins, so // keeping one shared mock avoids cross-test interference). diff --git a/app/src/analytics/reportWebVitals.ts b/app/src/analytics/reportWebVitals.ts index 809b0dc4af..0e4c9bba95 100644 --- a/app/src/analytics/reportWebVitals.ts +++ b/app/src/analytics/reportWebVitals.ts @@ -1,4 +1,4 @@ -import { getAnalyticsAmbientProps } from '../hooks/useAnalytics'; +import { getAnalyticsAmbientProps } from 'src/hooks/useAnalytics'; /** * Core Web Vitals tracking via web-vitals library. diff --git a/app/src/components/CodeHighlighter.test.tsx b/app/src/components/CodeHighlighter.test.tsx index e59deee2aa..4c00fb73f4 100644 --- a/app/src/components/CodeHighlighter.test.tsx +++ b/app/src/components/CodeHighlighter.test.tsx @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from 'vitest'; -import { render, screen } from '../test-utils'; +import { render, screen } from 'src/test-utils'; vi.mock('react-syntax-highlighter/dist/esm/prism-light', () => { const MockHighlighter = ({ @@ -45,7 +45,7 @@ vi.mock('react-syntax-highlighter/dist/esm/languages/prism/tsx', () => ({ default: {}, })); -import CodeHighlighter from './CodeHighlighter'; +import CodeHighlighter from 'src/components/CodeHighlighter'; describe('CodeHighlighter', () => { it('renders without crashing', () => { diff --git a/app/src/components/CodeHighlighter.tsx b/app/src/components/CodeHighlighter.tsx index 1b6ccd08f0..b2931ff090 100644 --- a/app/src/components/CodeHighlighter.tsx +++ b/app/src/components/CodeHighlighter.tsx @@ -5,7 +5,7 @@ import r from 'react-syntax-highlighter/dist/esm/languages/prism/r'; import tsx from 'react-syntax-highlighter/dist/esm/languages/prism/tsx'; import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-light'; -import { typography } from '../theme'; +import { typography } from 'src/theme'; SyntaxHighlighter.registerLanguage('python', python); SyntaxHighlighter.registerLanguage('r', r); diff --git a/app/src/components/CodeShowcase.tsx b/app/src/components/CodeShowcase.tsx index c9c35fd42e..7e391b61f2 100644 --- a/app/src/components/CodeShowcase.tsx +++ b/app/src/components/CodeShowcase.tsx @@ -1,7 +1,7 @@ import Box from '@mui/material/Box'; -import { typography } from '../theme'; -import { SectionHeader } from './SectionHeader'; +import { SectionHeader } from 'src/components/SectionHeader'; +import { typography } from 'src/theme'; export function CodeShowcase() { return ( diff --git a/app/src/components/ErrorBoundary.test.tsx b/app/src/components/ErrorBoundary.test.tsx index 079f40a4b0..be018c1aa9 100644 --- a/app/src/components/ErrorBoundary.test.tsx +++ b/app/src/components/ErrorBoundary.test.tsx @@ -2,9 +2,8 @@ import { ReactNode } from 'react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen } from '../test-utils'; -// Must import after test-utils to get jest-dom matchers -import { ErrorBoundary } from './ErrorBoundary'; +import { ErrorBoundary } from 'src/components/ErrorBoundary'; +import { render, screen } from 'src/test-utils'; // Component that throws on render function ThrowingComponent({ message }: { message: string }): ReactNode { @@ -58,7 +57,7 @@ describe('ErrorBoundary', () => { }); it('toggles technical details disclosure', async () => { - const { userEvent } = await import('../test-utils'); + const { userEvent } = await import('src/test-utils'); const user = userEvent.setup(); render( @@ -82,7 +81,7 @@ describe('ErrorBoundary', () => { }); it('copies details to the clipboard', async () => { - const { userEvent } = await import('../test-utils'); + const { userEvent } = await import('src/test-utils'); const user = userEvent.setup(); const writeText = vi.fn().mockResolvedValue(undefined); @@ -105,7 +104,7 @@ describe('ErrorBoundary', () => { }); it('recovers when Try Again is clicked', async () => { - const { userEvent } = await import('../test-utils'); + const { userEvent } = await import('src/test-utils'); const user = userEvent.setup(); // Use a flag to control whether the child throws diff --git a/app/src/components/FeedbackWidget.test.tsx b/app/src/components/FeedbackWidget.test.tsx index a0c33cc0a5..be5b48a00c 100644 --- a/app/src/components/FeedbackWidget.test.tsx +++ b/app/src/components/FeedbackWidget.test.tsx @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, userEvent, waitFor } from '../test-utils'; -import { FeedbackWidget } from './FeedbackWidget'; +import { FeedbackWidget } from 'src/components/FeedbackWidget'; +import { render, screen, userEvent, waitFor } from 'src/test-utils'; describe('FeedbackWidget', () => { beforeEach(() => { diff --git a/app/src/components/FeedbackWidget.tsx b/app/src/components/FeedbackWidget.tsx index 61d66f812b..30a315937d 100644 --- a/app/src/components/FeedbackWidget.tsx +++ b/app/src/components/FeedbackWidget.tsx @@ -16,10 +16,10 @@ import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import Tooltip from '@mui/material/Tooltip'; -import { API_URL } from '../constants'; -import { useAnalytics } from '../hooks'; -import { useLocalStorage } from '../hooks/useLocalStorage'; -import { RESERVED_TOP_LEVEL } from '../utils/paths'; +import { API_URL } from 'src/constants'; +import { useAnalytics } from 'src/hooks'; +import { useLocalStorage } from 'src/hooks/useLocalStorage'; +import { RESERVED_TOP_LEVEL } from 'src/utils/paths'; const MAX_MESSAGE_LENGTH = 500; const SESSION_KEY = 'anyplot_feedback_session'; diff --git a/app/src/components/FilterBar.test.tsx b/app/src/components/FilterBar.test.tsx index 5b27d244eb..e989a7de66 100644 --- a/app/src/components/FilterBar.test.tsx +++ b/app/src/components/FilterBar.test.tsx @@ -1,9 +1,9 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen } from '../test-utils'; +import { render, screen } from 'src/test-utils'; // Mock the utils module -vi.mock('../utils', () => ({ +vi.mock('src/utils', () => ({ getAvailableValues: vi.fn(() => [ ['scatter', 10], ['bar', 5], @@ -12,7 +12,7 @@ vi.mock('../utils', () => ({ getSearchResults: vi.fn(() => []), })); -import { FilterBar } from './FilterBar'; +import { FilterBar } from 'src/components/FilterBar'; // ResizeObserver polyfill class MockResizeObserver { diff --git a/app/src/components/FilterBar.tsx b/app/src/components/FilterBar.tsx index c06dca2713..7ee1e96951 100644 --- a/app/src/components/FilterBar.tsx +++ b/app/src/components/FilterBar.tsx @@ -15,17 +15,17 @@ import Tooltip from '@mui/material/Tooltip'; import Typography from '@mui/material/Typography'; import useMediaQuery from '@mui/material/useMediaQuery'; -import type { ImageSize } from '../constants'; -import { colors, fontSize, semanticColors, typography } from '../theme'; -import type { ActiveFilters, FilterCategory, FilterCounts } from '../types'; -import { FILTER_CATEGORIES, FILTER_LABELS, FILTER_TOOLTIPS } from '../types'; +import { ToolbarActions } from 'src/components/ToolbarActions'; +import type { ImageSize } from 'src/constants'; +import { colors, fontSize, semanticColors, typography } from 'src/theme'; +import type { ActiveFilters, FilterCategory, FilterCounts } from 'src/types'; +import { FILTER_CATEGORIES, FILTER_LABELS, FILTER_TOOLTIPS } from 'src/types'; import { getAvailableValues, getAvailableValuesForGroup, getSearchResults, type SearchResult, -} from '../utils'; -import { ToolbarActions } from './ToolbarActions'; +} from 'src/utils'; interface FilterBarProps { activeFilters: ActiveFilters; diff --git a/app/src/components/Footer.test.tsx b/app/src/components/Footer.test.tsx index d8eb9bdb96..cd770a432a 100644 --- a/app/src/components/Footer.test.tsx +++ b/app/src/components/Footer.test.tsx @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from 'vitest'; -import { render, screen, userEvent } from '../test-utils'; -import { Footer } from './Footer'; +import { Footer } from 'src/components/Footer'; +import { render, screen, userEvent } from 'src/test-utils'; describe('Footer', () => { it('renders footer links', () => { diff --git a/app/src/components/Footer.tsx b/app/src/components/Footer.tsx index 7672e1b12f..12397d6eba 100644 --- a/app/src/components/Footer.tsx +++ b/app/src/components/Footer.tsx @@ -3,8 +3,8 @@ import { Link as RouterLink } from 'react-router-dom'; import Box from '@mui/material/Box'; import Link from '@mui/material/Link'; -import { GITHUB_URL } from '../constants'; -import { colors, fontSize, semanticColors, typography } from '../theme'; +import { GITHUB_URL } from 'src/constants'; +import { colors, fontSize, semanticColors, typography } from 'src/theme'; interface FooterProps { onTrackEvent?: (name: string, props?: Record) => void; diff --git a/app/src/components/HeroSection.test.tsx b/app/src/components/HeroSection.test.tsx index 4c7d3608d7..2abb70c980 100644 --- a/app/src/components/HeroSection.test.tsx +++ b/app/src/components/HeroSection.test.tsx @@ -1,26 +1,26 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, userEvent } from '../test-utils'; +import { render, screen, userEvent } from 'src/test-utils'; const trackEvent = vi.fn(); -vi.mock('../hooks', async () => { - const actual = await vi.importActual('../hooks'); +vi.mock('src/hooks', async () => { + const actual = await vi.importActual('src/hooks'); return { ...actual, useAnalytics: () => ({ trackEvent, trackPageview: vi.fn() }), }; }); -vi.mock('./PlotOfTheDayTerminal', () => ({ +vi.mock('src/components/PlotOfTheDayTerminal', () => ({ PlotOfTheDayTerminal: () =>
, })); -vi.mock('./TypewriterText', () => ({ +vi.mock('src/components/TypewriterText', () => ({ TypewriterText: () =>
, })); -import { HeroSection } from './HeroSection'; +import { HeroSection } from 'src/components/HeroSection'; describe('HeroSection', () => { beforeEach(() => { diff --git a/app/src/components/HeroSection.tsx b/app/src/components/HeroSection.tsx index 2945396361..2585bd9074 100644 --- a/app/src/components/HeroSection.tsx +++ b/app/src/components/HeroSection.tsx @@ -2,11 +2,11 @@ import { Link as RouterLink } from 'react-router-dom'; import Box from '@mui/material/Box'; -import { useAnalytics } from '../hooks'; -import type { PlotOfTheDayData } from '../hooks/usePlotOfTheDay'; -import { colors, typography } from '../theme'; -import { PlotOfTheDayTerminal } from './PlotOfTheDayTerminal'; -import { TypewriterText } from './TypewriterText'; +import { PlotOfTheDayTerminal } from 'src/components/PlotOfTheDayTerminal'; +import { TypewriterText } from 'src/components/TypewriterText'; +import { useAnalytics } from 'src/hooks'; +import type { PlotOfTheDayData } from 'src/hooks/usePlotOfTheDay'; +import { colors, typography } from 'src/theme'; interface HeroSectionProps { potd?: PlotOfTheDayData | null; diff --git a/app/src/components/ImageCard.test.tsx b/app/src/components/ImageCard.test.tsx index 6d0b01d459..7ae1774279 100644 --- a/app/src/components/ImageCard.test.tsx +++ b/app/src/components/ImageCard.test.tsx @@ -1,12 +1,12 @@ import { describe, expect, it, vi } from 'vitest'; -import { render, screen } from '../test-utils'; -import type { PlotImage } from '../types'; -import { ImageCard } from './ImageCard'; +import { ImageCard } from 'src/components/ImageCard'; +import { render, screen } from 'src/test-utils'; +import type { PlotImage } from 'src/types'; // Mock useCodeFetch to avoid actual API calls; mirrors the real hook contract // (fetchCode, getCode, isLoading) so contract drift breaks this test. -vi.mock('../hooks/useCodeFetch', () => ({ +vi.mock('src/hooks/useCodeFetch', () => ({ useCodeFetch: () => ({ fetchCode: vi.fn().mockResolvedValue('print("hello")'), getCode: vi.fn().mockReturnValue(null), @@ -59,7 +59,7 @@ describe('ImageCard', () => { }); it('calls onClick when card is clicked', async () => { - const { userEvent } = await import('../test-utils'); + const { userEvent } = await import('src/test-utils'); const user = userEvent.setup(); const onClick = vi.fn(); @@ -77,7 +77,7 @@ describe('ImageCard', () => { }); it('toggles spec tooltip on spec_id click', async () => { - const { userEvent } = await import('../test-utils'); + const { userEvent } = await import('src/test-utils'); const user = userEvent.setup(); const onTooltipToggle = vi.fn(); @@ -111,7 +111,7 @@ describe('ImageCard', () => { }); it('toggles the language tooltip on click', async () => { - const { userEvent } = await import('../test-utils'); + const { userEvent } = await import('src/test-utils'); const user = userEvent.setup(); const onTooltipToggle = vi.fn(); render(); diff --git a/app/src/components/ImageCard.tsx b/app/src/components/ImageCard.tsx index 704978ccef..39e37da981 100644 --- a/app/src/components/ImageCard.tsx +++ b/app/src/components/ImageCard.tsx @@ -13,12 +13,12 @@ import Tooltip from '@mui/material/Tooltip'; import Typography from '@mui/material/Typography'; import useMediaQuery from '@mui/material/useMediaQuery'; -import { BATCH_SIZE, type ImageSize, LANG_DISPLAY, libExt } from '../constants'; -import { useCodeFetch } from '../hooks'; -import { colors, fontSize, semanticColors, typography } from '../theme'; -import type { PlotImage } from '../types'; -import { buildSrcSet, getFallbackSrc, getResponsiveSizes } from '../utils/responsiveImage'; -import { useThemedPreviewUrl } from '../utils/themedPreview'; +import { BATCH_SIZE, type ImageSize, LANG_DISPLAY, libExt } from 'src/constants'; +import { useCodeFetch } from 'src/hooks'; +import { colors, fontSize, semanticColors, typography } from 'src/theme'; +import type { PlotImage } from 'src/types'; +import { buildSrcSet, getFallbackSrc, getResponsiveSizes } from 'src/utils/responsiveImage'; +import { useThemedPreviewUrl } from 'src/utils/themedPreview'; // Library abbreviations for compact mode const LIBRARY_ABBR: Record = { diff --git a/app/src/components/ImagesGrid.test.tsx b/app/src/components/ImagesGrid.test.tsx index 029484a6ff..4eedcfcd52 100644 --- a/app/src/components/ImagesGrid.test.tsx +++ b/app/src/components/ImagesGrid.test.tsx @@ -2,19 +2,19 @@ import { createRef } from 'react'; import { describe, expect, it, type Mock, vi } from 'vitest'; -import type { ImageSize } from '../constants'; -import { render, screen } from '../test-utils'; -import type { LibraryInfo, PlotImage, SpecInfo } from '../types'; -import { ImagesGrid } from './ImagesGrid'; +import { ImagesGrid } from 'src/components/ImagesGrid'; +import type { ImageSize } from 'src/constants'; +import { render, screen } from 'src/test-utils'; +import type { LibraryInfo, PlotImage, SpecInfo } from 'src/types'; // Mock child components to isolate ImagesGrid -vi.mock('./ImageCard', () => ({ +vi.mock('src/components/ImageCard', () => ({ ImageCard: ({ image, index }: { image: PlotImage; index: number }) => (
{image.library}
), })); -vi.mock('./LoaderSpinner', () => ({ +vi.mock('src/components/LoaderSpinner', () => ({ LoaderSpinner: ({ size }: { size: string }) =>
{size}
, })); diff --git a/app/src/components/ImagesGrid.tsx b/app/src/components/ImagesGrid.tsx index 5b00f4074a..89bd93edb8 100644 --- a/app/src/components/ImagesGrid.tsx +++ b/app/src/components/ImagesGrid.tsx @@ -4,10 +4,10 @@ import Alert from '@mui/material/Alert'; import Box from '@mui/material/Box'; import Grid from '@mui/material/Grid'; -import type { ImageSize } from '../constants'; -import type { LanguageInfo, LibraryInfo, PlotImage, SpecInfo } from '../types'; -import { ImageCard } from './ImageCard'; -import { LoaderSpinner } from './LoaderSpinner'; +import { ImageCard } from 'src/components/ImageCard'; +import { LoaderSpinner } from 'src/components/LoaderSpinner'; +import type { ImageSize } from 'src/constants'; +import type { LanguageInfo, LibraryInfo, PlotImage, SpecInfo } from 'src/types'; interface ImagesGridProps { images: PlotImage[]; diff --git a/app/src/components/Layout.test.tsx b/app/src/components/Layout.test.tsx index 14d08bd3cf..03519562fe 100644 --- a/app/src/components/Layout.test.tsx +++ b/app/src/components/Layout.test.tsx @@ -1,8 +1,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { useAppData } from '../hooks/useLayoutContext'; -import { render, screen, waitFor } from '../test-utils'; -import { AppDataProvider } from './Layout'; +import { AppDataProvider } from 'src/components/Layout'; +import { useAppData } from 'src/hooks/useLayoutContext'; +import { render, screen, waitFor } from 'src/test-utils'; // Helper component that reads the context and renders the four counts // the user-reported NumbersStrip is built from. Acts as a black-box diff --git a/app/src/components/Layout.tsx b/app/src/components/Layout.tsx index d9a2b8404b..9e7b95d134 100644 --- a/app/src/components/Layout.tsx +++ b/app/src/components/Layout.tsx @@ -1,15 +1,15 @@ import { type ReactNode, useCallback, useEffect, useRef, useState } from 'react'; -import { API_URL } from '../constants'; +import { API_URL } from 'src/constants'; import { AppDataContext, type HomeState, HomeStateContext, initialHomeState, ThemeContext, -} from '../hooks/useLayoutContext'; -import { useThemeMode } from '../hooks/useThemeMode'; -import type { LanguageInfo, LibraryInfo, SpecInfo } from '../types'; +} from 'src/hooks/useLayoutContext'; +import { useThemeMode } from 'src/hooks/useThemeMode'; +import type { LanguageInfo, LibraryInfo, SpecInfo } from 'src/types'; // Global provider that wraps the entire router export function AppDataProvider({ children }: { children: ReactNode }) { diff --git a/app/src/components/LibrariesSection.tsx b/app/src/components/LibrariesSection.tsx index 4b25c4f8e1..211e607c50 100644 --- a/app/src/components/LibrariesSection.tsx +++ b/app/src/components/LibrariesSection.tsx @@ -1,9 +1,9 @@ import Box from '@mui/material/Box'; -import { LIBRARIES } from '../constants'; -import type { LibraryInfo } from '../types'; -import { LibraryCard } from './LibraryCard'; -import { SectionHeader } from './SectionHeader'; +import { LibraryCard } from 'src/components/LibraryCard'; +import { SectionHeader } from 'src/components/SectionHeader'; +import { LIBRARIES } from 'src/constants'; +import type { LibraryInfo } from 'src/types'; interface LibrariesSectionProps { libraries: LibraryInfo[]; diff --git a/app/src/components/LibraryCard.test.tsx b/app/src/components/LibraryCard.test.tsx index 126ee2525a..133c492941 100644 --- a/app/src/components/LibraryCard.test.tsx +++ b/app/src/components/LibraryCard.test.tsx @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from 'vitest'; -import { render, screen, userEvent } from '../test-utils'; -import { LibraryCard } from './LibraryCard'; +import { LibraryCard } from 'src/components/LibraryCard'; +import { render, screen, userEvent } from 'src/test-utils'; describe('LibraryCard', () => { it('renders the library name', () => { diff --git a/app/src/components/LibraryCard.tsx b/app/src/components/LibraryCard.tsx index 4f0b37b89f..b846a2bad4 100644 --- a/app/src/components/LibraryCard.tsx +++ b/app/src/components/LibraryCard.tsx @@ -1,7 +1,7 @@ import Box from '@mui/material/Box'; -import { LANG_DISPLAY, LIB_TO_FRAMEWORK } from '../constants'; -import { colors, typography } from '../theme'; +import { LANG_DISPLAY, LIB_TO_FRAMEWORK } from 'src/constants'; +import { colors, typography } from 'src/theme'; const DESCRIPTIONS: Record = { matplotlib: 'The foundation. Publication-ready figures with total control.', diff --git a/app/src/components/LibraryPills.test.tsx b/app/src/components/LibraryPills.test.tsx index c51e5bad73..8e36db6dc0 100644 --- a/app/src/components/LibraryPills.test.tsx +++ b/app/src/components/LibraryPills.test.tsx @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from 'vitest'; -import { render, screen, userEvent } from '../test-utils'; -import { LibraryPills } from './LibraryPills'; +import { LibraryPills } from 'src/components/LibraryPills'; +import { render, screen, userEvent } from 'src/test-utils'; const mockImplementations = [ { library_id: 'matplotlib', library_name: 'Matplotlib', language: 'python', quality_score: 85 }, diff --git a/app/src/components/LibraryPills.tsx b/app/src/components/LibraryPills.tsx index 4675448772..e28a411e6e 100644 --- a/app/src/components/LibraryPills.tsx +++ b/app/src/components/LibraryPills.tsx @@ -5,7 +5,7 @@ import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import Box from '@mui/material/Box'; import IconButton from '@mui/material/IconButton'; -import { colors, fontSize, semanticColors, typography } from '../theme'; +import { colors, fontSize, semanticColors, typography } from 'src/theme'; // Library abbreviations (same as filter display) const LIBRARY_ABBREV: Record = { diff --git a/app/src/components/LoaderSpinner.test.tsx b/app/src/components/LoaderSpinner.test.tsx index a8e55f9521..a547ff303d 100644 --- a/app/src/components/LoaderSpinner.test.tsx +++ b/app/src/components/LoaderSpinner.test.tsx @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; -import { render } from '../test-utils'; -import { LoaderSpinner } from './LoaderSpinner'; +import { LoaderSpinner } from 'src/components/LoaderSpinner'; +import { render } from 'src/test-utils'; describe('LoaderSpinner', () => { it('renders without crashing', () => { diff --git a/app/src/components/LoaderSpinner.tsx b/app/src/components/LoaderSpinner.tsx index c8231cbf63..9aa64e07d1 100644 --- a/app/src/components/LoaderSpinner.tsx +++ b/app/src/components/LoaderSpinner.tsx @@ -1,6 +1,6 @@ import Box from '@mui/material/Box'; -import { colors } from '../theme'; +import { colors } from 'src/theme'; interface LoaderSpinnerProps { size?: 'large' | 'small'; diff --git a/app/src/components/MastheadRule.test.tsx b/app/src/components/MastheadRule.test.tsx index 6271d37664..07bfc02d31 100644 --- a/app/src/components/MastheadRule.test.tsx +++ b/app/src/components/MastheadRule.test.tsx @@ -6,14 +6,14 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { createTheme, ThemeProvider } from '@mui/material/styles'; -import { render, screen, userEvent } from '../test-utils'; +import { render, screen, userEvent } from 'src/test-utils'; const trackEvent = vi.fn(); const cycle = vi.fn(); const setMode = vi.fn(); -vi.mock('../hooks', async () => { - const actual = await vi.importActual('../hooks'); +vi.mock('src/hooks', async () => { + const actual = await vi.importActual('src/hooks'); return { ...actual, useAnalytics: () => ({ trackEvent, trackPageview: vi.fn() }), @@ -22,7 +22,7 @@ vi.mock('../hooks', async () => { }; }); -import { MastheadRule } from './MastheadRule'; +import { MastheadRule } from 'src/components/MastheadRule'; function renderAt(initialEntry: string, ui: ReactElement) { const theme = createTheme(); diff --git a/app/src/components/MastheadRule.tsx b/app/src/components/MastheadRule.tsx index ee9dba9ee5..4e56444379 100644 --- a/app/src/components/MastheadRule.tsx +++ b/app/src/components/MastheadRule.tsx @@ -4,11 +4,11 @@ import { Link as RouterLink, useLocation } from 'react-router-dom'; import Box from '@mui/material/Box'; -import { LANG_EXT, LIB_ABBREV } from '../constants'; -import { useAnalytics, useLatestRelease, useTheme } from '../hooks'; -import { colors, typography } from '../theme'; -import { RESERVED_TOP_LEVEL } from '../utils/paths'; -import { ThemeToggle } from './ThemeToggle'; +import { ThemeToggle } from 'src/components/ThemeToggle'; +import { LANG_EXT, LIB_ABBREV } from 'src/constants'; +import { useAnalytics, useLatestRelease, useTheme } from 'src/hooks'; +import { colors, typography } from 'src/theme'; +import { RESERVED_TOP_LEVEL } from 'src/utils/paths'; // Symmetric block-comment delimiters used when no language context is in the URL. // One is picked on mount so each page load reveals a different classic. diff --git a/app/src/components/NavBar.test.tsx b/app/src/components/NavBar.test.tsx index 0bf2fd1ab9..1696288949 100644 --- a/app/src/components/NavBar.test.tsx +++ b/app/src/components/NavBar.test.tsx @@ -1,12 +1,12 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, userEvent } from '../test-utils'; +import { render, screen, userEvent } from 'src/test-utils'; const trackEvent = vi.fn(); const navigate = vi.fn(); -vi.mock('../hooks', async () => { - const actual = await vi.importActual('../hooks'); +vi.mock('src/hooks', async () => { + const actual = await vi.importActual('src/hooks'); return { ...actual, useAnalytics: () => ({ trackEvent, trackPageview: vi.fn() }), @@ -21,7 +21,7 @@ vi.mock('react-router-dom', async () => { }; }); -import { NavBar } from './NavBar'; +import { NavBar } from 'src/components/NavBar'; describe('NavBar', () => { beforeEach(() => { diff --git a/app/src/components/NavBar.tsx b/app/src/components/NavBar.tsx index 00f9e5dc2f..fd69973d1d 100644 --- a/app/src/components/NavBar.tsx +++ b/app/src/components/NavBar.tsx @@ -4,8 +4,8 @@ import { Link as RouterLink, useLocation, useNavigate } from 'react-router-dom'; import Box from '@mui/material/Box'; -import { useAnalytics } from '../hooks'; -import { colors, typography } from '../theme'; +import { useAnalytics } from 'src/hooks'; +import { colors, typography } from 'src/theme'; const DEBUG_CLICK_COUNT = 5; const DEBUG_CLICK_WINDOW_MS = 800; diff --git a/app/src/components/NumbersStrip.tsx b/app/src/components/NumbersStrip.tsx index af0375bf16..0e26c05cba 100644 --- a/app/src/components/NumbersStrip.tsx +++ b/app/src/components/NumbersStrip.tsx @@ -1,6 +1,6 @@ import Box from '@mui/material/Box'; -import { typography } from '../theme'; +import { typography } from 'src/theme'; interface NumbersStripProps { stats: { diff --git a/app/src/components/PlotOfTheDay.test.tsx b/app/src/components/PlotOfTheDay.test.tsx index acea6ad8c2..4115a77b52 100644 --- a/app/src/components/PlotOfTheDay.test.tsx +++ b/app/src/components/PlotOfTheDay.test.tsx @@ -1,18 +1,18 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, waitFor } from '../test-utils'; +import { render, screen, waitFor } from 'src/test-utils'; const trackEvent = vi.fn(); -vi.mock('../hooks', async () => { - const actual = await vi.importActual('../hooks'); +vi.mock('src/hooks', async () => { + const actual = await vi.importActual('src/hooks'); return { ...actual, useAnalytics: () => ({ trackEvent, trackPageview: vi.fn() }), }; }); -import { PlotOfTheDay } from './PlotOfTheDay'; +import { PlotOfTheDay } from 'src/components/PlotOfTheDay'; // Mock sessionStorage const sessionStorageMock: Record = {}; @@ -150,7 +150,7 @@ describe('PlotOfTheDay', () => { json: () => Promise.resolve(mockData), }); - const { userEvent } = await import('../test-utils'); + const { userEvent } = await import('src/test-utils'); const user = userEvent.setup(); const { container } = render(); @@ -177,7 +177,7 @@ describe('PlotOfTheDay', () => { json: () => Promise.resolve(mockData), }); - const { userEvent } = await import('../test-utils'); + const { userEvent } = await import('src/test-utils'); const user = userEvent.setup(); render(); diff --git a/app/src/components/PlotOfTheDay.tsx b/app/src/components/PlotOfTheDay.tsx index c8902364cf..114b9e4680 100644 --- a/app/src/components/PlotOfTheDay.tsx +++ b/app/src/components/PlotOfTheDay.tsx @@ -9,13 +9,13 @@ import IconButton from '@mui/material/IconButton'; import Link from '@mui/material/Link'; import Typography from '@mui/material/Typography'; -import { API_URL, GITHUB_URL } from '../constants'; -import { useAnalytics } from '../hooks'; -import { useTheme } from '../hooks/useLayoutContext'; -import { colors, fontSize, semanticColors, typography } from '../theme'; -import { specPath } from '../utils/paths'; -import { buildSrcSet, getFallbackSrc } from '../utils/responsiveImage'; -import { selectPreviewUrl } from '../utils/themedPreview'; +import { API_URL, GITHUB_URL } from 'src/constants'; +import { useAnalytics } from 'src/hooks'; +import { useTheme } from 'src/hooks/useLayoutContext'; +import { colors, fontSize, semanticColors, typography } from 'src/theme'; +import { specPath } from 'src/utils/paths'; +import { buildSrcSet, getFallbackSrc } from 'src/utils/responsiveImage'; +import { selectPreviewUrl } from 'src/utils/themedPreview'; interface PlotOfTheDayData { spec_id: string; diff --git a/app/src/components/PlotOfTheDayTerminal.test.tsx b/app/src/components/PlotOfTheDayTerminal.test.tsx index d52440d696..fa1cb1ce5d 100644 --- a/app/src/components/PlotOfTheDayTerminal.test.tsx +++ b/app/src/components/PlotOfTheDayTerminal.test.tsx @@ -1,25 +1,25 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, userEvent } from '../test-utils'; +import { render, screen, userEvent } from 'src/test-utils'; const trackEvent = vi.fn(); -vi.mock('../hooks', async () => { - const actual = await vi.importActual('../hooks'); +vi.mock('src/hooks', async () => { + const actual = await vi.importActual('src/hooks'); return { ...actual, useAnalytics: () => ({ trackEvent, trackPageview: vi.fn() }), }; }); -vi.mock('../hooks/useLayoutContext', async () => { - const actual = await vi.importActual( - '../hooks/useLayoutContext' +vi.mock('src/hooks/useLayoutContext', async () => { + const actual = await vi.importActual( + 'src/hooks/useLayoutContext' ); return { ...actual, useTheme: () => ({ isDark: false, toggle: vi.fn() }) }; }); -import { PlotOfTheDayTerminal } from './PlotOfTheDayTerminal'; +import { PlotOfTheDayTerminal } from 'src/components/PlotOfTheDayTerminal'; const potd = { spec_id: 'scatter-basic', diff --git a/app/src/components/PlotOfTheDayTerminal.tsx b/app/src/components/PlotOfTheDayTerminal.tsx index b6fd435961..686ece5e28 100644 --- a/app/src/components/PlotOfTheDayTerminal.tsx +++ b/app/src/components/PlotOfTheDayTerminal.tsx @@ -2,14 +2,14 @@ import { Link as RouterLink } from 'react-router-dom'; import Box from '@mui/material/Box'; -import { GITHUB_URL } from '../constants'; -import { useAnalytics } from '../hooks'; -import { useTheme } from '../hooks/useLayoutContext'; -import type { PlotOfTheDayData } from '../hooks/usePlotOfTheDay'; -import { colors, typography } from '../theme'; -import { specPath } from '../utils/paths'; -import { buildSrcSet, getFallbackSrc } from '../utils/responsiveImage'; -import { selectPreviewUrl } from '../utils/themedPreview'; +import { GITHUB_URL } from 'src/constants'; +import { useAnalytics } from 'src/hooks'; +import { useTheme } from 'src/hooks/useLayoutContext'; +import type { PlotOfTheDayData } from 'src/hooks/usePlotOfTheDay'; +import { colors, typography } from 'src/theme'; +import { specPath } from 'src/utils/paths'; +import { buildSrcSet, getFallbackSrc } from 'src/utils/responsiveImage'; +import { selectPreviewUrl } from 'src/utils/themedPreview'; interface PlotOfTheDayTerminalProps { potd: PlotOfTheDayData | null; diff --git a/app/src/components/RelatedSpecs.test.tsx b/app/src/components/RelatedSpecs.test.tsx index 13b684fe3a..c909408d35 100644 --- a/app/src/components/RelatedSpecs.test.tsx +++ b/app/src/components/RelatedSpecs.test.tsx @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, waitFor } from '../test-utils'; -import { RelatedSpecs } from './RelatedSpecs'; +import { RelatedSpecs } from 'src/components/RelatedSpecs'; +import { render, screen, waitFor } from 'src/test-utils'; describe('RelatedSpecs', () => { let fetchMock: ReturnType; @@ -122,7 +122,7 @@ describe('RelatedSpecs', () => { json: () => Promise.resolve({ related: mockRelated }), }); - const { userEvent } = await import('../test-utils'); + const { userEvent } = await import('src/test-utils'); const user = userEvent.setup(); const onHoverTags = vi.fn(); diff --git a/app/src/components/RelatedSpecs.tsx b/app/src/components/RelatedSpecs.tsx index c04771873a..1506deef99 100644 --- a/app/src/components/RelatedSpecs.tsx +++ b/app/src/components/RelatedSpecs.tsx @@ -9,12 +9,12 @@ import Tab from '@mui/material/Tab'; import Tabs from '@mui/material/Tabs'; import Typography from '@mui/material/Typography'; -import { API_URL, LIB_ABBREV } from '../constants'; -import { useTheme } from '../hooks/useLayoutContext'; -import { colors, fontSize, semanticColors, typography } from '../theme'; -import { specPath } from '../utils/paths'; -import { buildSrcSet, getFallbackSrc } from '../utils/responsiveImage'; -import { selectPreviewUrl } from '../utils/themedPreview'; +import { API_URL, LIB_ABBREV } from 'src/constants'; +import { useTheme } from 'src/hooks/useLayoutContext'; +import { colors, fontSize, semanticColors, typography } from 'src/theme'; +import { specPath } from 'src/utils/paths'; +import { buildSrcSet, getFallbackSrc } from 'src/utils/responsiveImage'; +import { selectPreviewUrl } from 'src/utils/themedPreview'; interface RelatedSpec { id: string; diff --git a/app/src/components/RootLayout.test.tsx b/app/src/components/RootLayout.test.tsx index baba826a2f..e657292edb 100644 --- a/app/src/components/RootLayout.test.tsx +++ b/app/src/components/RootLayout.test.tsx @@ -7,14 +7,14 @@ import { createTheme, ThemeProvider } from '@mui/material/styles'; const { setAmbient } = vi.hoisted(() => ({ setAmbient: vi.fn() })); -vi.mock('../hooks/useAnalytics', async () => { +vi.mock('src/hooks/useAnalytics', async () => { const actual = - await vi.importActual('../hooks/useAnalytics'); + await vi.importActual('src/hooks/useAnalytics'); return { ...actual, setAnalyticsAmbientProps: setAmbient }; }); -vi.mock('../hooks', async () => { - const actual = await vi.importActual('../hooks'); +vi.mock('src/hooks', async () => { + const actual = await vi.importActual('src/hooks'); return { ...actual, useAnalytics: () => ({ trackEvent: vi.fn(), trackPageview: vi.fn() }), @@ -22,9 +22,9 @@ vi.mock('../hooks', async () => { }; }); -vi.mock('../hooks/useLayoutContext', async () => { - const actual = await vi.importActual( - '../hooks/useLayoutContext' +vi.mock('src/hooks/useLayoutContext', async () => { + const actual = await vi.importActual( + 'src/hooks/useLayoutContext' ); return { ...actual, @@ -38,11 +38,13 @@ vi.mock('../hooks/useLayoutContext', async () => { }; }); -vi.mock('./MastheadRule', () => ({ MastheadRule: () =>
})); -vi.mock('./NavBar', () => ({ NavBar: () =>
})); -vi.mock('./Footer', () => ({ Footer: () =>
})); +vi.mock('src/components/MastheadRule', () => ({ + MastheadRule: () =>
, +})); +vi.mock('src/components/NavBar', () => ({ NavBar: () =>
})); +vi.mock('src/components/Footer', () => ({ Footer: () =>
})); -import { RootLayout } from './RootLayout'; +import { RootLayout } from 'src/components/RootLayout'; const theme = createTheme(); diff --git a/app/src/components/RootLayout.tsx b/app/src/components/RootLayout.tsx index e7de6e630a..bd7020ed66 100644 --- a/app/src/components/RootLayout.tsx +++ b/app/src/components/RootLayout.tsx @@ -5,13 +5,13 @@ import { Outlet, useLocation, useNavigationType } from 'react-router-dom'; import Box from '@mui/material/Box'; import Container from '@mui/material/Container'; -import { useAnalytics } from '../hooks'; -import { setAnalyticsAmbientProps } from '../hooks/useAnalytics'; -import { useTheme } from '../hooks/useLayoutContext'; -import { FeedbackWidget } from './FeedbackWidget'; -import { Footer } from './Footer'; -import { MastheadRule } from './MastheadRule'; -import { NavBar } from './NavBar'; +import { FeedbackWidget } from 'src/components/FeedbackWidget'; +import { Footer } from 'src/components/Footer'; +import { MastheadRule } from 'src/components/MastheadRule'; +import { NavBar } from 'src/components/NavBar'; +import { useAnalytics } from 'src/hooks'; +import { setAnalyticsAmbientProps } from 'src/hooks/useAnalytics'; +import { useTheme } from 'src/hooks/useLayoutContext'; const containerSx = { px: { xs: 2, sm: 4, md: 8, lg: 12 }, diff --git a/app/src/components/RouteErrorBoundary.test.tsx b/app/src/components/RouteErrorBoundary.test.tsx index c880f86b40..39ae0b684f 100644 --- a/app/src/components/RouteErrorBoundary.test.tsx +++ b/app/src/components/RouteErrorBoundary.test.tsx @@ -5,7 +5,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { createTheme, ThemeProvider } from '@mui/material/styles'; -import { RouteErrorBoundary } from './RouteErrorBoundary'; +import { RouteErrorBoundary } from 'src/components/RouteErrorBoundary'; vi.mock('react-helmet-async', () => ({ Helmet: ({ children }: { children: React.ReactNode }) => <>{children}, diff --git a/app/src/components/RouteErrorBoundary.tsx b/app/src/components/RouteErrorBoundary.tsx index 3038a2dcca..e2206313c3 100644 --- a/app/src/components/RouteErrorBoundary.tsx +++ b/app/src/components/RouteErrorBoundary.tsx @@ -10,7 +10,7 @@ import Button from '@mui/material/Button'; import CircularProgress from '@mui/material/CircularProgress'; import Typography from '@mui/material/Typography'; -import { NotFoundPage } from '../pages/NotFoundPage'; +import { NotFoundPage } from 'src/pages/NotFoundPage'; const RELOAD_ATTEMPT_KEY = 'anyplot:chunk-reload-attempt'; diff --git a/app/src/components/ScienceNote.tsx b/app/src/components/ScienceNote.tsx index 5d05b5907c..b747c9a299 100644 --- a/app/src/components/ScienceNote.tsx +++ b/app/src/components/ScienceNote.tsx @@ -2,8 +2,8 @@ import { Link as RouterLink } from 'react-router-dom'; import Box from '@mui/material/Box'; -import { colors, typography } from '../theme'; -import { PaletteStrip } from './PaletteStrip'; +import { PaletteStrip } from 'src/components/PaletteStrip'; +import { colors, typography } from 'src/theme'; export function ScienceNote() { return ( diff --git a/app/src/components/SectionHeader.test.tsx b/app/src/components/SectionHeader.test.tsx index b12e21e20c..8d4b4d4709 100644 --- a/app/src/components/SectionHeader.test.tsx +++ b/app/src/components/SectionHeader.test.tsx @@ -1,18 +1,18 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, userEvent } from '../test-utils'; +import { render, screen, userEvent } from 'src/test-utils'; const trackEvent = vi.fn(); -vi.mock('../hooks', async () => { - const actual = await vi.importActual('../hooks'); +vi.mock('src/hooks', async () => { + const actual = await vi.importActual('src/hooks'); return { ...actual, useAnalytics: () => ({ trackEvent, trackPageview: vi.fn() }), }; }); -import { SectionHeader } from './SectionHeader'; +import { SectionHeader } from 'src/components/SectionHeader'; describe('SectionHeader', () => { beforeEach(() => { diff --git a/app/src/components/SectionHeader.tsx b/app/src/components/SectionHeader.tsx index f3ccf6a15b..7d621b75c5 100644 --- a/app/src/components/SectionHeader.tsx +++ b/app/src/components/SectionHeader.tsx @@ -2,8 +2,8 @@ import { Link } from 'react-router-dom'; import Box from '@mui/material/Box'; -import { useAnalytics } from '../hooks'; -import { colors, typography } from '../theme'; +import { useAnalytics } from 'src/hooks'; +import { colors, typography } from 'src/theme'; interface SectionHeaderBaseProps { /** Prefix symbol — e.g. `§`, `❯`, `$`. Rendered at the same size as the title. */ diff --git a/app/src/components/SpecDetailView.test.tsx b/app/src/components/SpecDetailView.test.tsx index 71e50d664b..8edfc32370 100644 --- a/app/src/components/SpecDetailView.test.tsx +++ b/app/src/components/SpecDetailView.test.tsx @@ -1,9 +1,9 @@ import { describe, expect, it, vi } from 'vitest'; -import { ThemeContext, type ThemeContextValue } from '../hooks/useLayoutContext'; -import { render, screen, userEvent } from '../test-utils'; -import type { Implementation } from '../types'; -import { SpecDetailView } from './SpecDetailView'; +import { SpecDetailView } from 'src/components/SpecDetailView'; +import { ThemeContext, type ThemeContextValue } from 'src/hooks/useLayoutContext'; +import { render, screen, userEvent } from 'src/test-utils'; +import type { Implementation } from 'src/types'; const darkThemeValue: ThemeContextValue = { mode: 'dark', @@ -13,7 +13,7 @@ const darkThemeValue: ThemeContextValue = { cycle: vi.fn(), }; -vi.mock('../utils/responsiveImage', () => ({ +vi.mock('src/utils/responsiveImage', () => ({ buildDetailSrcSet: (url: string, fmt: string) => `${url}-srcset-${fmt}`, DETAIL_SIZES: '100vw', })); diff --git a/app/src/components/SpecDetailView.tsx b/app/src/components/SpecDetailView.tsx index 908a90ed11..eb9aae1412 100644 --- a/app/src/components/SpecDetailView.tsx +++ b/app/src/components/SpecDetailView.tsx @@ -18,12 +18,12 @@ import IconButton from '@mui/material/IconButton'; import Skeleton from '@mui/material/Skeleton'; import Tooltip from '@mui/material/Tooltip'; -import { API_URL } from '../constants'; -import { useTheme } from '../hooks/useLayoutContext'; -import { colors, fontSize, typography } from '../theme'; -import type { Implementation } from '../types'; -import { buildDetailSrcSet, DETAIL_SIZES } from '../utils/responsiveImage'; -import { selectPreviewHtml, selectPreviewUrl } from '../utils/themedPreview'; +import { API_URL } from 'src/constants'; +import { useTheme } from 'src/hooks/useLayoutContext'; +import { colors, fontSize, typography } from 'src/theme'; +import type { Implementation } from 'src/types'; +import { buildDetailSrcSet, DETAIL_SIZES } from 'src/utils/responsiveImage'; +import { selectPreviewHtml, selectPreviewUrl } from 'src/utils/themedPreview'; const INITIAL_WIDTH = 1600; const INITIAL_HEIGHT = 900; diff --git a/app/src/components/SpecOverview.test.tsx b/app/src/components/SpecOverview.test.tsx index 6d483752ec..b013e19f98 100644 --- a/app/src/components/SpecOverview.test.tsx +++ b/app/src/components/SpecOverview.test.tsx @@ -1,10 +1,10 @@ import { describe, expect, it, vi } from 'vitest'; -import { render, screen, userEvent } from '../test-utils'; -import type { Implementation } from '../types'; -import { SpecOverview } from './SpecOverview'; +import { SpecOverview } from 'src/components/SpecOverview'; +import { render, screen, userEvent } from 'src/test-utils'; +import type { Implementation } from 'src/types'; -vi.mock('../utils/responsiveImage', () => ({ +vi.mock('src/utils/responsiveImage', () => ({ buildSrcSet: (url: string, fmt: string) => `${url}-srcset-${fmt}`, OVERVIEW_SIZES: '33vw', })); diff --git a/app/src/components/SpecOverview.tsx b/app/src/components/SpecOverview.tsx index ec094cd7ba..0c8aeb5084 100644 --- a/app/src/components/SpecOverview.tsx +++ b/app/src/components/SpecOverview.tsx @@ -19,12 +19,12 @@ import Skeleton from '@mui/material/Skeleton'; import Tooltip from '@mui/material/Tooltip'; import Typography from '@mui/material/Typography'; -import { useTheme } from '../hooks/useLayoutContext'; -import { colors, fontSize, semanticColors, typography } from '../theme'; -import type { Implementation } from '../types'; -import { specPath } from '../utils/paths'; -import { buildSrcSet, OVERVIEW_SIZES } from '../utils/responsiveImage'; -import { selectPreviewUrl } from '../utils/themedPreview'; +import { useTheme } from 'src/hooks/useLayoutContext'; +import { colors, fontSize, semanticColors, typography } from 'src/theme'; +import type { Implementation } from 'src/types'; +import { specPath } from 'src/utils/paths'; +import { buildSrcSet, OVERVIEW_SIZES } from 'src/utils/responsiveImage'; +import { selectPreviewUrl } from 'src/utils/themedPreview'; interface LibraryMeta { id: string; diff --git a/app/src/components/SpecTabs.test.tsx b/app/src/components/SpecTabs.test.tsx index 875f06f576..5c8009188d 100644 --- a/app/src/components/SpecTabs.test.tsx +++ b/app/src/components/SpecTabs.test.tsx @@ -1,15 +1,15 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, userEvent, waitFor } from '../test-utils'; -import { SpecTabs } from './SpecTabs'; +import { SpecTabs } from 'src/components/SpecTabs'; +import { render, screen, userEvent, waitFor } from 'src/test-utils'; // Mock the lazy-loaded CodeHighlighter -vi.mock('./CodeHighlighter', () => ({ +vi.mock('src/components/CodeHighlighter', () => ({ default: ({ code }: { code: string }) =>
{code}
, })); // Mock the constants module to avoid import.meta issues -vi.mock('../constants', () => ({ +vi.mock('src/constants', () => ({ API_URL: 'http://localhost:8000', })); diff --git a/app/src/components/SpecTabs.tsx b/app/src/components/SpecTabs.tsx index 711dc4fc95..34645af96a 100644 --- a/app/src/components/SpecTabs.tsx +++ b/app/src/components/SpecTabs.tsx @@ -19,9 +19,9 @@ import Tabs from '@mui/material/Tabs'; import Tooltip from '@mui/material/Tooltip'; import Typography from '@mui/material/Typography'; -const CodeHighlighter = lazy(() => import('./CodeHighlighter')); -import { API_URL } from '../constants'; -import { colors, fontSize, semanticColors, typography } from '../theme'; +const CodeHighlighter = lazy(() => import('src/components/CodeHighlighter')); +import { API_URL } from 'src/constants'; +import { colors, fontSize, semanticColors, typography } from 'src/theme'; // Cached global tag counts — loaded once, shared across all SpecTabs instances let cachedTagCounts: Record> | null = null; diff --git a/app/src/components/ThemeToggle.tsx b/app/src/components/ThemeToggle.tsx index 1ebc9082da..bf7345a910 100644 --- a/app/src/components/ThemeToggle.tsx +++ b/app/src/components/ThemeToggle.tsx @@ -1,7 +1,7 @@ import Box from '@mui/material/Box'; -import type { ThemeMode } from '../hooks/useLayoutContext'; -import { colors, typography } from '../theme'; +import type { ThemeMode } from 'src/hooks/useLayoutContext'; +import { colors, typography } from 'src/theme'; interface ThemeToggleProps { mode: ThemeMode; diff --git a/app/src/components/ToolbarActions.test.tsx b/app/src/components/ToolbarActions.test.tsx index 2f36ce9c55..0820bae7e1 100644 --- a/app/src/components/ToolbarActions.test.tsx +++ b/app/src/components/ToolbarActions.test.tsx @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from 'vitest'; -import { render, screen, userEvent } from '../test-utils'; -import { GridSizeToggle, PlotsLink, ToolbarActions } from './ToolbarActions'; +import { GridSizeToggle, PlotsLink, ToolbarActions } from 'src/components/ToolbarActions'; +import { render, screen, userEvent } from 'src/test-utils'; describe('PlotsLink', () => { it('renders a link to /plots', () => { diff --git a/app/src/components/ToolbarActions.tsx b/app/src/components/ToolbarActions.tsx index 7a7049a0c6..dc04558c40 100644 --- a/app/src/components/ToolbarActions.tsx +++ b/app/src/components/ToolbarActions.tsx @@ -11,8 +11,8 @@ import ViewModuleIcon from '@mui/icons-material/ViewModule'; import Box from '@mui/material/Box'; import Tooltip from '@mui/material/Tooltip'; -import type { ImageSize } from '../constants'; -import { colors, semanticColors } from '../theme'; +import type { ImageSize } from 'src/constants'; +import { colors, semanticColors } from 'src/theme'; interface ToolbarActionsProps { imageSize: ImageSize; diff --git a/app/src/components/TypewriterText.tsx b/app/src/components/TypewriterText.tsx index 65ea142466..8977f4c823 100644 --- a/app/src/components/TypewriterText.tsx +++ b/app/src/components/TypewriterText.tsx @@ -2,8 +2,8 @@ import { useEffect, useState } from 'react'; import Box from '@mui/material/Box'; -import { useTypewriter } from '../hooks/useTypewriter'; -import { colors } from '../theme'; +import { useTypewriter } from 'src/hooks/useTypewriter'; +import { colors } from 'src/theme'; interface TypewriterTextProps { lines: string[]; diff --git a/app/src/hooks/index.ts b/app/src/hooks/index.ts index 0aba15478d..acf0704c85 100644 --- a/app/src/hooks/index.ts +++ b/app/src/hooks/index.ts @@ -1,17 +1,17 @@ -export { useInfiniteScroll } from './useInfiniteScroll'; -export { useAnalytics } from './useAnalytics'; -export { useCopyCode } from './useCopyCode'; -export { useCodeFetch } from './useCodeFetch'; -export { useLocalStorage } from './useLocalStorage'; -export { useFilterState, isFiltersEmpty } from './useFilterState'; -export { useUrlSync, parseUrlFilters, buildFilterUrl } from './useUrlSync'; -export { useFilterFetch } from './useFilterFetch'; -export { useAppData, useHomeState, useTheme } from './useLayoutContext'; +export { useInfiniteScroll } from 'src/hooks/useInfiniteScroll'; +export { useAnalytics } from 'src/hooks/useAnalytics'; +export { useCopyCode } from 'src/hooks/useCopyCode'; +export { useCodeFetch } from 'src/hooks/useCodeFetch'; +export { useLocalStorage } from 'src/hooks/useLocalStorage'; +export { useFilterState, isFiltersEmpty } from 'src/hooks/useFilterState'; +export { useUrlSync, parseUrlFilters, buildFilterUrl } from 'src/hooks/useUrlSync'; +export { useFilterFetch } from 'src/hooks/useFilterFetch'; +export { useAppData, useHomeState, useTheme } from 'src/hooks/useLayoutContext'; export type { HomeState, HomeStateContextValue, AppData, ThemeContextValue, -} from './useLayoutContext'; -export { useThemeMode } from './useThemeMode'; -export { useLatestRelease } from './useLatestRelease'; +} from 'src/hooks/useLayoutContext'; +export { useThemeMode } from 'src/hooks/useThemeMode'; +export { useLatestRelease } from 'src/hooks/useLatestRelease'; diff --git a/app/src/hooks/useAnalytics.test.ts b/app/src/hooks/useAnalytics.test.ts index 8e8fc234f9..daf7b43d94 100644 --- a/app/src/hooks/useAnalytics.test.ts +++ b/app/src/hooks/useAnalytics.test.ts @@ -1,7 +1,7 @@ import { act, renderHook } from '@testing-library/react'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { setAnalyticsAmbientProps, useAnalytics } from './useAnalytics'; +import { setAnalyticsAmbientProps, useAnalytics } from 'src/hooks/useAnalytics'; describe('useAnalytics', () => { const originalLocation = window.location; diff --git a/app/src/hooks/useAnalytics.ts b/app/src/hooks/useAnalytics.ts index 4f088b6d46..677542e4dc 100644 --- a/app/src/hooks/useAnalytics.ts +++ b/app/src/hooks/useAnalytics.ts @@ -1,6 +1,6 @@ import { useCallback, useMemo, useRef } from 'react'; -import { RESERVED_TOP_LEVEL } from '../utils/paths'; +import { RESERVED_TOP_LEVEL } from 'src/utils/paths'; interface EventProps { [key: string]: string | undefined; diff --git a/app/src/hooks/useCodeFetch.test.ts b/app/src/hooks/useCodeFetch.test.ts index e4c16e280f..327269039e 100644 --- a/app/src/hooks/useCodeFetch.test.ts +++ b/app/src/hooks/useCodeFetch.test.ts @@ -1,7 +1,7 @@ import { act, renderHook } from '@testing-library/react'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { useCodeFetch } from './useCodeFetch'; +import { useCodeFetch } from 'src/hooks/useCodeFetch'; describe('useCodeFetch', () => { beforeEach(() => { diff --git a/app/src/hooks/useCodeFetch.ts b/app/src/hooks/useCodeFetch.ts index 41e55926b2..98f3026de4 100644 --- a/app/src/hooks/useCodeFetch.ts +++ b/app/src/hooks/useCodeFetch.ts @@ -7,7 +7,7 @@ import { useCallback, useRef, useState } from 'react'; -import { API_URL } from '../constants'; +import { API_URL } from 'src/constants'; interface CodeCache { [key: string]: string | null; // key: `${spec_id}:${language}:${library}` diff --git a/app/src/hooks/useCopyCode.test.ts b/app/src/hooks/useCopyCode.test.ts index 963682883a..86e4c5acbd 100644 --- a/app/src/hooks/useCopyCode.test.ts +++ b/app/src/hooks/useCopyCode.test.ts @@ -1,7 +1,7 @@ import { act, renderHook } from '@testing-library/react'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { useCopyCode } from './useCopyCode'; +import { useCopyCode } from 'src/hooks/useCopyCode'; describe('useCopyCode', () => { beforeEach(() => { diff --git a/app/src/hooks/useFeaturedSpecs.ts b/app/src/hooks/useFeaturedSpecs.ts index cee18231d8..6ef387021b 100644 --- a/app/src/hooks/useFeaturedSpecs.ts +++ b/app/src/hooks/useFeaturedSpecs.ts @@ -1,9 +1,9 @@ import { useEffect, useMemo, useState } from 'react'; -import { API_URL } from '../constants'; -import type { PlotImage } from '../types'; -import { shuffleArray } from '../utils/shuffle'; -import { useAppData } from './useLayoutContext'; +import { API_URL } from 'src/constants'; +import { useAppData } from 'src/hooks/useLayoutContext'; +import type { PlotImage } from 'src/types'; +import { shuffleArray } from 'src/utils/shuffle'; function pickRandom(items: T[]): T { return items[Math.floor(Math.random() * items.length)]; diff --git a/app/src/hooks/useFilterFetch.test.ts b/app/src/hooks/useFilterFetch.test.ts index d7ee3a4bcc..4ab4bbb4f0 100644 --- a/app/src/hooks/useFilterFetch.test.ts +++ b/app/src/hooks/useFilterFetch.test.ts @@ -1,8 +1,8 @@ import { renderHook, waitFor } from '@testing-library/react'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import type { ActiveFilters, PlotImage } from '../types'; -import { useFilterFetch } from './useFilterFetch'; +import { useFilterFetch } from 'src/hooks/useFilterFetch'; +import type { ActiveFilters, PlotImage } from 'src/types'; describe('useFilterFetch', () => { let fetchMock: ReturnType; diff --git a/app/src/hooks/useFilterFetch.ts b/app/src/hooks/useFilterFetch.ts index 46e1ee1c3b..9a0c7f43a5 100644 --- a/app/src/hooks/useFilterFetch.ts +++ b/app/src/hooks/useFilterFetch.ts @@ -6,9 +6,9 @@ import { useEffect, useMemo, useRef, useState } from 'react'; -import { API_URL, BATCH_SIZE } from '../constants'; -import type { ActiveFilters, FilterCounts, PlotImage } from '../types'; -import { shuffleArray } from '../utils/shuffle'; +import { API_URL, BATCH_SIZE } from 'src/constants'; +import type { ActiveFilters, FilterCounts, PlotImage } from 'src/types'; +import { shuffleArray } from 'src/utils/shuffle'; interface FilterFetchState { filterCounts: FilterCounts | null; diff --git a/app/src/hooks/useFilterState-extended.test.ts b/app/src/hooks/useFilterState-extended.test.ts index 3a48be19e9..e9e55d0cbc 100644 --- a/app/src/hooks/useFilterState-extended.test.ts +++ b/app/src/hooks/useFilterState-extended.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; -import type { ActiveFilters } from '../types'; -import { isFiltersEmpty } from './useFilterState'; +import { isFiltersEmpty } from 'src/hooks/useFilterState'; +import type { ActiveFilters } from 'src/types'; describe('isFiltersEmpty - extended', () => { it('returns true for a single group with empty values', () => { diff --git a/app/src/hooks/useFilterState-imagesKey.test.ts b/app/src/hooks/useFilterState-imagesKey.test.ts index 5a5c28c338..db1faa953f 100644 --- a/app/src/hooks/useFilterState-imagesKey.test.ts +++ b/app/src/hooks/useFilterState-imagesKey.test.ts @@ -8,8 +8,8 @@ import { describe, expect, it } from 'vitest'; -import type { PlotImage } from '../types'; -import { imagesContentKey } from './useFilterState'; +import { imagesContentKey } from 'src/hooks/useFilterState'; +import type { PlotImage } from 'src/types'; function img(spec_id: string, library: string, extra: Partial = {}): PlotImage { return { diff --git a/app/src/hooks/useFilterState.test.ts b/app/src/hooks/useFilterState.test.ts index b8faec8a65..18822c9b2e 100644 --- a/app/src/hooks/useFilterState.test.ts +++ b/app/src/hooks/useFilterState.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; -import type { ActiveFilters } from '../types'; -import { isFiltersEmpty } from './useFilterState'; +import { isFiltersEmpty } from 'src/hooks/useFilterState'; +import type { ActiveFilters } from 'src/types'; describe('isFiltersEmpty', () => { it('returns true for empty array', () => { diff --git a/app/src/hooks/useFilterState.ts b/app/src/hooks/useFilterState.ts index ac8bd866ff..e7cda901af 100644 --- a/app/src/hooks/useFilterState.ts +++ b/app/src/hooks/useFilterState.ts @@ -7,11 +7,11 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import type { ActiveFilters, FilterCategory, FilterCounts, PlotImage } from '../types'; -import { FILTER_CATEGORIES } from '../types'; -import { useFilterFetch } from './useFilterFetch'; -import { useHomeState } from './useLayoutContext'; -import { parseUrlFilters, useUrlSync } from './useUrlSync'; +import { useFilterFetch } from 'src/hooks/useFilterFetch'; +import { useHomeState } from 'src/hooks/useLayoutContext'; +import { parseUrlFilters, useUrlSync } from 'src/hooks/useUrlSync'; +import type { ActiveFilters, FilterCategory, FilterCounts, PlotImage } from 'src/types'; +import { FILTER_CATEGORIES } from 'src/types'; /** * Check if filters are empty. diff --git a/app/src/hooks/useInfiniteScroll.test.ts b/app/src/hooks/useInfiniteScroll.test.ts index c3a0e44165..6782da2fe5 100644 --- a/app/src/hooks/useInfiniteScroll.test.ts +++ b/app/src/hooks/useInfiniteScroll.test.ts @@ -1,9 +1,9 @@ import { act, renderHook } from '@testing-library/react'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { BATCH_SIZE } from '../constants'; -import type { PlotImage } from '../types'; -import { useInfiniteScroll } from './useInfiniteScroll'; +import { BATCH_SIZE } from 'src/constants'; +import { useInfiniteScroll } from 'src/hooks/useInfiniteScroll'; +import type { PlotImage } from 'src/types'; // --- IntersectionObserver mock --- let observerCallback: IntersectionObserverCallback; diff --git a/app/src/hooks/useInfiniteScroll.ts b/app/src/hooks/useInfiniteScroll.ts index 0bc924d85d..3f93dc4985 100644 --- a/app/src/hooks/useInfiniteScroll.ts +++ b/app/src/hooks/useInfiniteScroll.ts @@ -1,7 +1,7 @@ import { useCallback, useEffect, useRef } from 'react'; -import { BATCH_SIZE } from '../constants'; -import type { PlotImage } from '../types'; +import { BATCH_SIZE } from 'src/constants'; +import type { PlotImage } from 'src/types'; interface UseInfiniteScrollProps { allImages: PlotImage[]; diff --git a/app/src/hooks/useLatestRelease.test.ts b/app/src/hooks/useLatestRelease.test.ts index c21ed2f09e..261b79a4b5 100644 --- a/app/src/hooks/useLatestRelease.test.ts +++ b/app/src/hooks/useLatestRelease.test.ts @@ -1,7 +1,7 @@ import { renderHook, waitFor } from '@testing-library/react'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { useLatestRelease } from './useLatestRelease'; +import { useLatestRelease } from 'src/hooks/useLatestRelease'; const CACHE_KEY = 'anyplot:latest-release'; const ONE_HOUR = 60 * 60 * 1000; diff --git a/app/src/hooks/useLayoutContext.test.ts b/app/src/hooks/useLayoutContext.test.ts index b823ca63d1..600ceae06f 100644 --- a/app/src/hooks/useLayoutContext.test.ts +++ b/app/src/hooks/useLayoutContext.test.ts @@ -1,7 +1,7 @@ import { renderHook } from '@testing-library/react'; import { describe, expect, it } from 'vitest'; -import { initialHomeState, useAppData, useHomeState } from './useLayoutContext'; +import { initialHomeState, useAppData, useHomeState } from 'src/hooks/useLayoutContext'; describe('useAppData', () => { it('throws when used outside provider', () => { diff --git a/app/src/hooks/useLayoutContext.ts b/app/src/hooks/useLayoutContext.ts index 146cffb3a0..3b9b2cf3da 100644 --- a/app/src/hooks/useLayoutContext.ts +++ b/app/src/hooks/useLayoutContext.ts @@ -1,6 +1,6 @@ import { createContext, useContext } from 'react'; -import type { ActiveFilters, FilterCounts, PlotImage } from '../types'; +import type { ActiveFilters, FilterCounts, PlotImage } from 'src/types'; // Persistent home state that survives navigation export interface HomeState { @@ -23,9 +23,9 @@ export interface HomeStateContextValue { } export interface AppData { - specsData: import('../types').SpecInfo[]; - librariesData: import('../types').LibraryInfo[]; - languagesData: import('../types').LanguageInfo[]; + specsData: import('src/types').SpecInfo[]; + librariesData: import('src/types').LibraryInfo[]; + languagesData: import('src/types').LanguageInfo[]; stats: { specs: number; plots: number; libraries: number; lines_of_code?: number } | null; } diff --git a/app/src/hooks/useLocalStorage.test.ts b/app/src/hooks/useLocalStorage.test.ts index 3acce16925..73329b6ce6 100644 --- a/app/src/hooks/useLocalStorage.test.ts +++ b/app/src/hooks/useLocalStorage.test.ts @@ -1,7 +1,7 @@ import { act, renderHook } from '@testing-library/react'; import { beforeEach, describe, expect, it } from 'vitest'; -import { useLocalStorage } from './useLocalStorage'; +import { useLocalStorage } from 'src/hooks/useLocalStorage'; describe('useLocalStorage', () => { beforeEach(() => { diff --git a/app/src/hooks/usePlotOfTheDay.ts b/app/src/hooks/usePlotOfTheDay.ts index baf1b71af9..cfc8f82ebe 100644 --- a/app/src/hooks/usePlotOfTheDay.ts +++ b/app/src/hooks/usePlotOfTheDay.ts @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; -import { API_URL } from '../constants'; +import { API_URL } from 'src/constants'; export interface PlotOfTheDayData { spec_id: string; diff --git a/app/src/hooks/useThemeMode.test.ts b/app/src/hooks/useThemeMode.test.ts index 39dc4cce9a..955529b3a2 100644 --- a/app/src/hooks/useThemeMode.test.ts +++ b/app/src/hooks/useThemeMode.test.ts @@ -1,7 +1,7 @@ import { act, renderHook } from '@testing-library/react'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { useThemeMode } from './useThemeMode'; +import { useThemeMode } from 'src/hooks/useThemeMode'; type MQListener = (e: MediaQueryListEvent) => void; diff --git a/app/src/hooks/useUrlSync.test.ts b/app/src/hooks/useUrlSync.test.ts index 7e63d8e85e..bbb12366c1 100644 --- a/app/src/hooks/useUrlSync.test.ts +++ b/app/src/hooks/useUrlSync.test.ts @@ -1,8 +1,8 @@ import { renderHook } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import type { ActiveFilters } from '../types'; -import { buildFilterUrl, parseUrlFilters, useUrlSync } from './useUrlSync'; +import { buildFilterUrl, parseUrlFilters, useUrlSync } from 'src/hooks/useUrlSync'; +import type { ActiveFilters } from 'src/types'; describe('parseUrlFilters', () => { beforeEach(() => { diff --git a/app/src/hooks/useUrlSync.ts b/app/src/hooks/useUrlSync.ts index c3eaf00247..88f07c7829 100644 --- a/app/src/hooks/useUrlSync.ts +++ b/app/src/hooks/useUrlSync.ts @@ -6,8 +6,8 @@ import { useEffect } from 'react'; -import type { ActiveFilters } from '../types'; -import { FILTER_CATEGORIES } from '../types'; +import type { ActiveFilters } from 'src/types'; +import { FILTER_CATEGORIES } from 'src/types'; /** * Parse URL params into ActiveFilters. diff --git a/app/src/main.tsx b/app/src/main.tsx index 123eca577a..a6e98ec5a4 100644 --- a/app/src/main.tsx +++ b/app/src/main.tsx @@ -1,7 +1,7 @@ // Import design tokens (CSS custom properties for theming + dark mode) -import './styles/tokens.css'; +import 'src/styles/tokens.css'; // Import web fonts - MonoLisa from GCS, Fraunces + Inter from Google Fonts -import './styles/fonts.css'; +import 'src/styles/fonts.css'; import React from 'react'; import ReactDOM from 'react-dom/client'; @@ -9,9 +9,9 @@ import ReactDOM from 'react-dom/client'; import CssBaseline from '@mui/material/CssBaseline'; import { createTheme, ThemeProvider } from '@mui/material/styles'; -import { reportWebVitals } from './analytics/reportWebVitals'; -import { AppRouter } from './router'; -import { colors, fontSize, typography } from './theme'; +import { reportWebVitals } from 'src/analytics/reportWebVitals'; +import { AppRouter } from 'src/router'; +import { colors, fontSize, typography } from 'src/theme'; const theme = createTheme({ typography: { diff --git a/app/src/pages/AboutPage.tsx b/app/src/pages/AboutPage.tsx index 2b9b9287e7..57a853bb19 100644 --- a/app/src/pages/AboutPage.tsx +++ b/app/src/pages/AboutPage.tsx @@ -6,10 +6,10 @@ import { Link as RouterLink } from 'react-router-dom'; import Box from '@mui/material/Box'; import Link from '@mui/material/Link'; -import { SectionHeader } from '../components/SectionHeader'; -import { GITHUB_URL } from '../constants'; -import { useAnalytics } from '../hooks'; -import { codeBlockStyle, colors, proseLinkStyle, textStyle, typography } from '../theme'; +import { SectionHeader } from 'src/components/SectionHeader'; +import { GITHUB_URL } from 'src/constants'; +import { useAnalytics } from 'src/hooks'; +import { codeBlockStyle, colors, proseLinkStyle, textStyle, typography } from 'src/theme'; const PIPELINE_BLOCK = `// pipeline idea → human-submitted (github issue) diff --git a/app/src/pages/DebugPage.test.tsx b/app/src/pages/DebugPage.test.tsx index 8ce6e04abe..18c5c550c1 100644 --- a/app/src/pages/DebugPage.test.tsx +++ b/app/src/pages/DebugPage.test.tsx @@ -1,8 +1,8 @@ import { fireEvent } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, waitFor } from '../test-utils'; -import { DebugPage } from './DebugPage'; +import { DebugPage } from 'src/pages/DebugPage'; +import { render, screen, waitFor } from 'src/test-utils'; const mockDebugData = { total_specs: 100, diff --git a/app/src/pages/DebugPage.tsx b/app/src/pages/DebugPage.tsx index a58036586b..52f40342e7 100644 --- a/app/src/pages/DebugPage.tsx +++ b/app/src/pages/DebugPage.tsx @@ -10,12 +10,12 @@ import Link from '@mui/material/Link'; import Tooltip from '@mui/material/Tooltip'; import Typography from '@mui/material/Typography'; -import { SectionHeader } from '../components/SectionHeader'; -import { DEBUG_API_URL, LIB_ABBREV, LIB_TO_LANG, LIBRARIES } from '../constants'; -import { useCopyCode } from '../hooks'; -import { colors, fontSize, semanticColors, typography } from '../theme'; -import { buildClaudePrompt } from '../utils/claudePrompt'; -import { specPath } from '../utils/paths'; +import { SectionHeader } from 'src/components/SectionHeader'; +import { DEBUG_API_URL, LIB_ABBREV, LIB_TO_LANG, LIBRARIES } from 'src/constants'; +import { useCopyCode } from 'src/hooks'; +import { colors, fontSize, semanticColors, typography } from 'src/theme'; +import { buildClaudePrompt } from 'src/utils/claudePrompt'; +import { specPath } from 'src/utils/paths'; // ============================================================================ // Types diff --git a/app/src/pages/LandingPage.test.tsx b/app/src/pages/LandingPage.test.tsx index a21db561b0..087a320b81 100644 --- a/app/src/pages/LandingPage.test.tsx +++ b/app/src/pages/LandingPage.test.tsx @@ -1,13 +1,13 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, userEvent } from '../test-utils'; +import { render, screen, userEvent } from 'src/test-utils'; const trackEvent = vi.fn(); const trackPageview = vi.fn(); const navigate = vi.fn(); -vi.mock('../hooks', async () => { - const actual = await vi.importActual('../hooks'); +vi.mock('src/hooks', async () => { + const actual = await vi.importActual('src/hooks'); return { ...actual, useAnalytics: () => ({ trackEvent, trackPageview }), @@ -19,7 +19,7 @@ vi.mock('../hooks', async () => { }; }); -vi.mock('../hooks/useFeaturedSpecs', () => ({ +vi.mock('src/hooks/useFeaturedSpecs', () => ({ useFeaturedSpecs: () => [ { spec_id: 'scatter-basic', @@ -33,13 +33,13 @@ vi.mock('../hooks/useFeaturedSpecs', () => ({ ], })); -vi.mock('../hooks/usePlotOfTheDay', () => ({ +vi.mock('src/hooks/usePlotOfTheDay', () => ({ usePlotOfTheDay: () => null, })); -vi.mock('../hooks/useLayoutContext', async () => { - const actual = await vi.importActual( - '../hooks/useLayoutContext' +vi.mock('src/hooks/useLayoutContext', async () => { + const actual = await vi.importActual( + 'src/hooks/useLayoutContext' ); return { ...actual, useTheme: () => ({ isDark: false, toggle: vi.fn() }) }; }); @@ -49,11 +49,11 @@ vi.mock('react-router-dom', async () => { return { ...actual, useNavigate: () => navigate }; }); -vi.mock('../components/HeroSection', () => ({ +vi.mock('src/components/HeroSection', () => ({ HeroSection: () =>
, })); -vi.mock('../components/NumbersStrip', () => ({ +vi.mock('src/components/NumbersStrip', () => ({ NumbersStrip: () =>
, })); @@ -63,7 +63,7 @@ vi.mock('react-helmet-async', () => ({ ), })); -import { LandingPage } from './LandingPage'; +import { LandingPage } from 'src/pages/LandingPage'; describe('LandingPage', () => { beforeEach(() => { diff --git a/app/src/pages/LandingPage.tsx b/app/src/pages/LandingPage.tsx index b59bbdae43..fc0dc58290 100644 --- a/app/src/pages/LandingPage.tsx +++ b/app/src/pages/LandingPage.tsx @@ -5,19 +5,19 @@ import { Link as RouterLink, useNavigate } from 'react-router-dom'; import Box from '@mui/material/Box'; -import { HeroSection } from '../components/HeroSection'; -import { LibrariesSection } from '../components/LibrariesSection'; -import { NumbersStrip } from '../components/NumbersStrip'; -import { SectionHeader } from '../components/SectionHeader'; -import { GITHUB_URL } from '../constants'; -import { useAnalytics, useAppData } from '../hooks'; -import { type FeaturedImpl, useFeaturedSpecs } from '../hooks/useFeaturedSpecs'; -import { useTheme } from '../hooks/useLayoutContext'; -import { usePlotOfTheDay } from '../hooks/usePlotOfTheDay'; -import { colors, semanticColors, typography } from '../theme'; -import { specPath } from '../utils/paths'; -import { buildSrcSet, getFallbackSrc } from '../utils/responsiveImage'; -import { selectPreviewUrl } from '../utils/themedPreview'; +import { HeroSection } from 'src/components/HeroSection'; +import { LibrariesSection } from 'src/components/LibrariesSection'; +import { NumbersStrip } from 'src/components/NumbersStrip'; +import { SectionHeader } from 'src/components/SectionHeader'; +import { GITHUB_URL } from 'src/constants'; +import { useAnalytics, useAppData } from 'src/hooks'; +import { type FeaturedImpl, useFeaturedSpecs } from 'src/hooks/useFeaturedSpecs'; +import { useTheme } from 'src/hooks/useLayoutContext'; +import { usePlotOfTheDay } from 'src/hooks/usePlotOfTheDay'; +import { colors, semanticColors, typography } from 'src/theme'; +import { specPath } from 'src/utils/paths'; +import { buildSrcSet, getFallbackSrc } from 'src/utils/responsiveImage'; +import { selectPreviewUrl } from 'src/utils/themedPreview'; export function LandingPage() { const { librariesData, stats } = useAppData(); diff --git a/app/src/pages/LegalPage.test.tsx b/app/src/pages/LegalPage.test.tsx index 4f079144b5..9a64ca96ef 100644 --- a/app/src/pages/LegalPage.test.tsx +++ b/app/src/pages/LegalPage.test.tsx @@ -1,15 +1,15 @@ import { fireEvent } from '@testing-library/react'; import { describe, expect, it, vi } from 'vitest'; -import { render, screen } from '../test-utils'; -import { LegalPage } from './LegalPage'; +import { LegalPage } from 'src/pages/LegalPage'; +import { render, screen } from 'src/test-utils'; vi.mock('react-helmet-async', () => ({ Helmet: ({ children }: { children: React.ReactNode }) => <>{children}, })); const trackEvent = vi.fn(); -vi.mock('../hooks', () => ({ +vi.mock('src/hooks', () => ({ useAnalytics: () => ({ trackPageview: vi.fn(), trackEvent: (...args: unknown[]) => trackEvent(...args), diff --git a/app/src/pages/LegalPage.tsx b/app/src/pages/LegalPage.tsx index 0b34061b0d..1b72898495 100644 --- a/app/src/pages/LegalPage.tsx +++ b/app/src/pages/LegalPage.tsx @@ -10,9 +10,9 @@ import TableCell from '@mui/material/TableCell'; import TableRow from '@mui/material/TableRow'; import Typography from '@mui/material/Typography'; -import { SectionHeader } from '../components/SectionHeader'; -import { GITHUB_URL } from '../constants'; -import { useAnalytics } from '../hooks'; +import { SectionHeader } from 'src/components/SectionHeader'; +import { GITHUB_URL } from 'src/constants'; +import { useAnalytics } from 'src/hooks'; import { fontSize, proseLinkStyle, @@ -20,7 +20,7 @@ import { subheadingStyle, tableStyle, textStyle, -} from '../theme'; +} from 'src/theme'; const firstColStyle = { '& .MuiTableCell-root:first-of-type': { diff --git a/app/src/pages/LibrariesPage.test.tsx b/app/src/pages/LibrariesPage.test.tsx index c3446aaf3d..2dee917985 100644 --- a/app/src/pages/LibrariesPage.test.tsx +++ b/app/src/pages/LibrariesPage.test.tsx @@ -2,14 +2,14 @@ import type { ReactNode } from 'react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, userEvent } from '../test-utils'; +import { render, screen, userEvent } from 'src/test-utils'; const trackEvent = vi.fn(); const trackPageview = vi.fn(); const navigate = vi.fn(); -vi.mock('../hooks', async () => { - const actual = await vi.importActual('../hooks'); +vi.mock('src/hooks', async () => { + const actual = await vi.importActual('src/hooks'); return { ...actual, useAnalytics: () => ({ trackEvent, trackPageview }), @@ -33,7 +33,7 @@ vi.mock('react-router-dom', async () => { return { ...actual, useNavigate: () => navigate }; }); -import { LibrariesPage } from './LibrariesPage'; +import { LibrariesPage } from 'src/pages/LibrariesPage'; describe('LibrariesPage', () => { beforeEach(() => { diff --git a/app/src/pages/LibrariesPage.tsx b/app/src/pages/LibrariesPage.tsx index f3ee01fa72..ee8bb5d34f 100644 --- a/app/src/pages/LibrariesPage.tsx +++ b/app/src/pages/LibrariesPage.tsx @@ -6,11 +6,11 @@ import { useNavigate } from 'react-router-dom'; import Box from '@mui/material/Box'; import Link from '@mui/material/Link'; -import { LibraryCard } from '../components/LibraryCard'; -import { SectionHeader } from '../components/SectionHeader'; -import { LIB_TO_FRAMEWORK, LIBRARIES } from '../constants'; -import { useAnalytics, useAppData } from '../hooks'; -import { colors, textStyle, typography } from '../theme'; +import { LibraryCard } from 'src/components/LibraryCard'; +import { SectionHeader } from 'src/components/SectionHeader'; +import { LIB_TO_FRAMEWORK, LIBRARIES } from 'src/constants'; +import { useAnalytics, useAppData } from 'src/hooks'; +import { colors, textStyle, typography } from 'src/theme'; // Framework filter (per library-expansion.md §6: "all JavaScript libs" vs // "React-compatible"). Built generically off LIB_TO_FRAMEWORK so adding a diff --git a/app/src/pages/MapPage.helpers.test.ts b/app/src/pages/MapPage.helpers.test.ts index 7b34e5d213..677169101a 100644 --- a/app/src/pages/MapPage.helpers.test.ts +++ b/app/src/pages/MapPage.helpers.test.ts @@ -13,7 +13,7 @@ import { type SpecMapItem, topPlotTypes, weightedJaccard, -} from './MapPage.helpers'; +} from 'src/pages/MapPage.helpers'; function spec( id: string, diff --git a/app/src/pages/MapPage.helpers.ts b/app/src/pages/MapPage.helpers.ts index 85c46d8a9d..34e31b397e 100644 --- a/app/src/pages/MapPage.helpers.ts +++ b/app/src/pages/MapPage.helpers.ts @@ -10,7 +10,7 @@ * canvas refresh. */ -import { selectPreviewUrl } from '../utils/themedPreview'; +import { selectPreviewUrl } from 'src/utils/themedPreview'; /** Backend response shape from GET /api/specs/map. Mirrors api/schemas.py::SpecMapItem. */ export interface SpecMapItem { diff --git a/app/src/pages/MapPage.test.tsx b/app/src/pages/MapPage.test.tsx index 7eff55c119..6df3a054d2 100644 --- a/app/src/pages/MapPage.test.tsx +++ b/app/src/pages/MapPage.test.tsx @@ -3,8 +3,8 @@ import { forwardRef, useImperativeHandle } from 'react'; import { fireEvent } from '@testing-library/react'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { act, render, screen, waitFor } from '../test-utils'; -import { MapPage, outlierSquashForce, type SimNode } from './MapPage'; +import { MapPage, outlierSquashForce, type SimNode } from 'src/pages/MapPage'; +import { act, render, screen, waitFor } from 'src/test-utils'; vi.mock('react-helmet-async', () => ({ Helmet: ({ children }: { children: React.ReactNode }) => <>{children}, @@ -18,14 +18,14 @@ vi.mock('react-router-dom', async () => { return { ...actual, useNavigate: () => mockNavigate }; }); -vi.mock('../hooks', () => ({ +vi.mock('src/hooks', () => ({ useAnalytics: () => ({ trackPageview: vi.fn(), trackEvent: mockTrackEvent, }), })); -vi.mock('../hooks/useLayoutContext', () => ({ +vi.mock('src/hooks/useLayoutContext', () => ({ useTheme: () => ({ isDark: false }), })); diff --git a/app/src/pages/MapPage.tsx b/app/src/pages/MapPage.tsx index 6b77d01515..659bbad950 100644 --- a/app/src/pages/MapPage.tsx +++ b/app/src/pages/MapPage.tsx @@ -11,11 +11,9 @@ import Slider from '@mui/material/Slider'; import Typography from '@mui/material/Typography'; import useMediaQuery from '@mui/material/useMediaQuery'; -import { API_URL } from '../constants'; -import { useAnalytics } from '../hooks'; -import { useTheme } from '../hooks/useLayoutContext'; -import { colors, fontSize, typography } from '../theme'; -import { specPath } from '../utils/paths'; +import { API_URL } from 'src/constants'; +import { useAnalytics } from 'src/hooks'; +import { useTheme } from 'src/hooks/useLayoutContext'; import { buildKNNLinks, buildVariantUrl, @@ -38,7 +36,9 @@ import { TAG_CATEGORIES, type TagCategory, topCategoryValues, -} from './MapPage.helpers'; +} from 'src/pages/MapPage.helpers'; +import { colors, fontSize, typography } from 'src/theme'; +import { specPath } from 'src/utils/paths'; const NODE_SIZE = 60; // graph-space size of a node — large enough to read the thumbnail without hovering const COOLDOWN_TICKS = 300; // simulation lifetime in ticks; the engine cap and alpha-decay below both derive from this so they stop together diff --git a/app/src/pages/McpPage.test.tsx b/app/src/pages/McpPage.test.tsx index 7fe74c20f8..a39f95786c 100644 --- a/app/src/pages/McpPage.test.tsx +++ b/app/src/pages/McpPage.test.tsx @@ -1,13 +1,13 @@ import { describe, expect, it, vi } from 'vitest'; -import { render, screen } from '../test-utils'; -import { McpPage } from './McpPage'; +import { McpPage } from 'src/pages/McpPage'; +import { render, screen } from 'src/test-utils'; vi.mock('react-helmet-async', () => ({ Helmet: ({ children }: { children: React.ReactNode }) => <>{children}, })); -vi.mock('../hooks', () => ({ +vi.mock('src/hooks', () => ({ useAnalytics: () => ({ trackPageview: vi.fn(), trackEvent: vi.fn(), diff --git a/app/src/pages/McpPage.tsx b/app/src/pages/McpPage.tsx index 974a17b43b..6dc182f89e 100644 --- a/app/src/pages/McpPage.tsx +++ b/app/src/pages/McpPage.tsx @@ -11,9 +11,9 @@ import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; import Typography from '@mui/material/Typography'; -import { SectionHeader } from '../components/SectionHeader'; -import { GITHUB_URL } from '../constants'; -import { useAnalytics } from '../hooks'; +import { SectionHeader } from 'src/components/SectionHeader'; +import { GITHUB_URL } from 'src/constants'; +import { useAnalytics } from 'src/hooks'; import { codeBlockStyle, proseLinkStyle, @@ -21,7 +21,7 @@ import { tableStyle, textStyle, typography, -} from '../theme'; +} from 'src/theme'; const inlineCodeSx = { fontFamily: typography.mono, diff --git a/app/src/pages/NotFoundPage.test.tsx b/app/src/pages/NotFoundPage.test.tsx index cfaed62e8d..9381f6c3d8 100644 --- a/app/src/pages/NotFoundPage.test.tsx +++ b/app/src/pages/NotFoundPage.test.tsx @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from 'vitest'; -import { render, screen } from '../test-utils'; -import { NotFoundPage } from './NotFoundPage'; +import { NotFoundPage } from 'src/pages/NotFoundPage'; +import { render, screen } from 'src/test-utils'; // Mock react-helmet-async to avoid provider requirement vi.mock('react-helmet-async', () => ({ diff --git a/app/src/pages/NotFoundPage.tsx b/app/src/pages/NotFoundPage.tsx index eaaa6f9223..ae508361ca 100644 --- a/app/src/pages/NotFoundPage.tsx +++ b/app/src/pages/NotFoundPage.tsx @@ -4,7 +4,7 @@ import { Link } from 'react-router-dom'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; -import { colors, semanticColors, typography } from '../theme'; +import { colors, semanticColors, typography } from 'src/theme'; export function NotFoundPage() { return ( diff --git a/app/src/pages/PalettePage.snippet.test.ts b/app/src/pages/PalettePage.snippet.test.ts index bea05015f7..3b0e55153d 100644 --- a/app/src/pages/PalettePage.snippet.test.ts +++ b/app/src/pages/PalettePage.snippet.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { type Lang, PALETTE, snippet } from './PalettePage'; +import { type Lang, PALETTE, snippet } from 'src/pages/PalettePage'; const LANGS: Lang[] = ['python', 'r', 'julia', 'js']; diff --git a/app/src/pages/PalettePage.tsx b/app/src/pages/PalettePage.tsx index 43da30e53e..890db11354 100644 --- a/app/src/pages/PalettePage.tsx +++ b/app/src/pages/PalettePage.tsx @@ -12,10 +12,10 @@ import Tab from '@mui/material/Tab'; import Tabs from '@mui/material/Tabs'; import Tooltip from '@mui/material/Tooltip'; -import { SectionHeader } from '../components/SectionHeader'; -import matrixData from '../data/paletteMatrices.json'; -import { useAnalytics, useTheme } from '../hooks'; -import { colors, fontSize, textStyle, typography } from '../theme'; +import { SectionHeader } from 'src/components/SectionHeader'; +import matrixData from 'src/data/paletteMatrices.json'; +import { useAnalytics, useTheme } from 'src/hooks'; +import { colors, fontSize, textStyle, typography } from 'src/theme'; // ───────────────────────────────────────────────────────────────────────────── // Imprint palette — 8 categorical hues + OKLCH coords for the wheel diff --git a/app/src/pages/PlotsPage.test.tsx b/app/src/pages/PlotsPage.test.tsx index 25f11b81b1..84ad15ab3e 100644 --- a/app/src/pages/PlotsPage.test.tsx +++ b/app/src/pages/PlotsPage.test.tsx @@ -1,8 +1,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen } from '../test-utils'; +import { render, screen } from 'src/test-utils'; -vi.mock('../hooks', () => ({ +vi.mock('src/hooks', () => ({ useAnalytics: () => ({ trackPageview: vi.fn(), trackEvent: vi.fn() }), useInfiniteScroll: () => ({ loadMoreRef: { current: null } }), useFilterState: () => ({ @@ -42,19 +42,19 @@ vi.mock('react-helmet-async', () => ({ ), })); -vi.mock('../components/FilterBar', () => ({ +vi.mock('src/components/FilterBar', () => ({ FilterBar: () =>
FilterBar
, })); -vi.mock('../components/ImagesGrid', () => ({ +vi.mock('src/components/ImagesGrid', () => ({ ImagesGrid: () =>
ImagesGrid
, })); -vi.mock('../components/Footer', () => ({ +vi.mock('src/components/Footer', () => ({ Footer: () =>
Footer
, })); -import { PlotsPage } from './PlotsPage'; +import { PlotsPage } from 'src/pages/PlotsPage'; describe('PlotsPage', () => { beforeEach(() => { diff --git a/app/src/pages/PlotsPage.tsx b/app/src/pages/PlotsPage.tsx index aa796cda89..fd5313be44 100644 --- a/app/src/pages/PlotsPage.tsx +++ b/app/src/pages/PlotsPage.tsx @@ -8,14 +8,14 @@ import Alert from '@mui/material/Alert'; import Box from '@mui/material/Box'; import Fab from '@mui/material/Fab'; -import { FilterBar } from '../components/FilterBar'; -import { ImagesGrid } from '../components/ImagesGrid'; -import type { ImageSize } from '../constants'; -import { isFiltersEmpty, useAnalytics, useFilterState, useInfiniteScroll } from '../hooks'; -import { useAppData, useHomeState } from '../hooks'; -import { colors } from '../theme'; -import type { PlotImage } from '../types'; -import { specPath } from '../utils/paths'; +import { FilterBar } from 'src/components/FilterBar'; +import { ImagesGrid } from 'src/components/ImagesGrid'; +import type { ImageSize } from 'src/constants'; +import { isFiltersEmpty, useAnalytics, useFilterState, useInfiniteScroll } from 'src/hooks'; +import { useAppData, useHomeState } from 'src/hooks'; +import { colors } from 'src/theme'; +import type { PlotImage } from 'src/types'; +import { specPath } from 'src/utils/paths'; export function PlotsPage() { const navigate = useNavigate(); diff --git a/app/src/pages/SpecPage.test.tsx b/app/src/pages/SpecPage.test.tsx index c8e0e01156..e981ced09a 100644 --- a/app/src/pages/SpecPage.test.tsx +++ b/app/src/pages/SpecPage.test.tsx @@ -1,7 +1,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, waitFor } from '../test-utils'; -import { SpecPage } from './SpecPage'; +import { SpecPage } from 'src/pages/SpecPage'; +import { render, screen, waitFor } from 'src/test-utils'; const mockNavigate = vi.fn(); let mockParams: Record = { specId: 'scatter-basic' }; @@ -22,7 +22,7 @@ vi.mock('react-helmet-async', () => ({ Helmet: ({ children }: { children: React.ReactNode }) => <>{children}, })); -vi.mock('../hooks', () => ({ +vi.mock('src/hooks', () => ({ useAnalytics: () => ({ trackPageview: vi.fn(), trackEvent: vi.fn(), @@ -41,15 +41,15 @@ vi.mock('../hooks', () => ({ })); // Mock lazy-loaded components as simple divs -vi.mock('../components/SpecTabs', () => ({ +vi.mock('src/components/SpecTabs', () => ({ SpecTabs: () =>
SpecTabs
, })); -vi.mock('../components/SpecOverview', () => ({ +vi.mock('src/components/SpecOverview', () => ({ SpecOverview: () =>
SpecOverview
, })); -vi.mock('../components/SpecDetailView', () => ({ +vi.mock('src/components/SpecDetailView', () => ({ SpecDetailView: () =>
SpecDetailView
, })); diff --git a/app/src/pages/SpecPage.tsx b/app/src/pages/SpecPage.tsx index 171faef446..0b93f0eb3d 100644 --- a/app/src/pages/SpecPage.tsx +++ b/app/src/pages/SpecPage.tsx @@ -9,23 +9,23 @@ import Button from '@mui/material/Button'; import Skeleton from '@mui/material/Skeleton'; import Typography from '@mui/material/Typography'; -import { LibraryPills } from '../components/LibraryPills'; -import { RelatedSpecs } from '../components/RelatedSpecs'; -import { API_URL, GITHUB_URL, LANG_DISPLAY } from '../constants'; -import { useAnalytics, useCodeFetch } from '../hooks'; -import { useAppData } from '../hooks'; -import { colors, fontSize, semanticColors, typography } from '../theme'; -import { specPath } from '../utils/paths'; -import { NotFoundPage } from './NotFoundPage'; - -const SpecTabs = lazy(() => import('../components/SpecTabs').then(m => ({ default: m.SpecTabs }))); +import { LibraryPills } from 'src/components/LibraryPills'; +import { RelatedSpecs } from 'src/components/RelatedSpecs'; +import { API_URL, GITHUB_URL, LANG_DISPLAY } from 'src/constants'; +import { useAnalytics, useCodeFetch } from 'src/hooks'; +import { useAppData } from 'src/hooks'; +import { NotFoundPage } from 'src/pages/NotFoundPage'; +import { colors, fontSize, semanticColors, typography } from 'src/theme'; +import { specPath } from 'src/utils/paths'; + +const SpecTabs = lazy(() => import('src/components/SpecTabs').then(m => ({ default: m.SpecTabs }))); const SpecOverview = lazy(() => - import('../components/SpecOverview').then(m => ({ default: m.SpecOverview })) + import('src/components/SpecOverview').then(m => ({ default: m.SpecOverview })) ); const SpecDetailView = lazy(() => - import('../components/SpecDetailView').then(m => ({ default: m.SpecDetailView })) + import('src/components/SpecDetailView').then(m => ({ default: m.SpecDetailView })) ); -import type { Implementation } from '../types'; +import type { Implementation } from 'src/types'; interface SpecDetail { id: string; diff --git a/app/src/pages/SpecsListPage.test.tsx b/app/src/pages/SpecsListPage.test.tsx index b60e51c9f0..236484673f 100644 --- a/app/src/pages/SpecsListPage.test.tsx +++ b/app/src/pages/SpecsListPage.test.tsx @@ -1,13 +1,13 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, waitFor } from '../test-utils'; -import { SpecsListPage } from './SpecsListPage'; +import { SpecsListPage } from 'src/pages/SpecsListPage'; +import { render, screen, waitFor } from 'src/test-utils'; vi.mock('react-helmet-async', () => ({ Helmet: ({ children }: { children: React.ReactNode }) => <>{children}, })); -vi.mock('../hooks', () => ({ +vi.mock('src/hooks', () => ({ useAnalytics: () => ({ trackPageview: vi.fn(), trackEvent: vi.fn(), @@ -23,7 +23,7 @@ vi.mock('../hooks', () => ({ }), })); -vi.mock('../utils/responsiveImage', () => ({ +vi.mock('src/utils/responsiveImage', () => ({ buildSrcSet: (url: string, _format: string) => url, getFallbackSrc: (url: string) => url, SPECS_SIZES: '280px', diff --git a/app/src/pages/SpecsListPage.tsx b/app/src/pages/SpecsListPage.tsx index b6884fcc05..e18eeda38a 100644 --- a/app/src/pages/SpecsListPage.tsx +++ b/app/src/pages/SpecsListPage.tsx @@ -9,14 +9,14 @@ import Fab from '@mui/material/Fab'; import Skeleton from '@mui/material/Skeleton'; import Typography from '@mui/material/Typography'; -import { SectionHeader } from '../components/SectionHeader'; -import { API_URL, GITHUB_URL } from '../constants'; -import { useAnalytics } from '../hooks'; -import { useAppData, useHomeState } from '../hooks'; -import { colors, fontSize, semanticColors, typography } from '../theme'; -import type { PlotImage } from '../types'; -import { specPath } from '../utils/paths'; -import { buildSrcSet, getFallbackSrc, SPECS_SIZES } from '../utils/responsiveImage'; +import { SectionHeader } from 'src/components/SectionHeader'; +import { API_URL, GITHUB_URL } from 'src/constants'; +import { useAnalytics } from 'src/hooks'; +import { useAppData, useHomeState } from 'src/hooks'; +import { colors, fontSize, semanticColors, typography } from 'src/theme'; +import type { PlotImage } from 'src/types'; +import { specPath } from 'src/utils/paths'; +import { buildSrcSet, getFallbackSrc, SPECS_SIZES } from 'src/utils/responsiveImage'; interface SpecListItem { id: string; diff --git a/app/src/pages/StatsPage.test.tsx b/app/src/pages/StatsPage.test.tsx index 058fb596de..d8d273dd28 100644 --- a/app/src/pages/StatsPage.test.tsx +++ b/app/src/pages/StatsPage.test.tsx @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { render, screen, userEvent, waitFor } from '../test-utils'; -import { StatsPage } from './StatsPage'; +import { StatsPage } from 'src/pages/StatsPage'; +import { render, screen, userEvent, waitFor } from 'src/test-utils'; vi.mock('react-helmet-async', () => ({ Helmet: ({ children }: { children: React.ReactNode }) => <>{children}, @@ -9,7 +9,7 @@ vi.mock('react-helmet-async', () => ({ const mockTrackEvent = vi.fn(); -vi.mock('../hooks', () => ({ +vi.mock('src/hooks', () => ({ useAnalytics: () => ({ trackPageview: vi.fn(), trackEvent: mockTrackEvent, diff --git a/app/src/pages/StatsPage.tsx b/app/src/pages/StatsPage.tsx index 725616ec03..7d2ea9f254 100644 --- a/app/src/pages/StatsPage.tsx +++ b/app/src/pages/StatsPage.tsx @@ -8,14 +8,14 @@ import Link from '@mui/material/Link'; import Tooltip from '@mui/material/Tooltip'; import Typography from '@mui/material/Typography'; -import { SectionHeader } from '../components/SectionHeader'; -import { API_URL } from '../constants'; -import { useAnalytics } from '../hooks'; -import { useTheme } from '../hooks/useLayoutContext'; -import { colors, fontSize, semanticColors, typography } from '../theme'; -import { specPath } from '../utils/paths'; -import { buildSrcSet, getFallbackSrc } from '../utils/responsiveImage'; -import { selectPreviewUrl } from '../utils/themedPreview'; +import { SectionHeader } from 'src/components/SectionHeader'; +import { API_URL } from 'src/constants'; +import { useAnalytics } from 'src/hooks'; +import { useTheme } from 'src/hooks/useLayoutContext'; +import { colors, fontSize, semanticColors, typography } from 'src/theme'; +import { specPath } from 'src/utils/paths'; +import { buildSrcSet, getFallbackSrc } from 'src/utils/responsiveImage'; +import { selectPreviewUrl } from 'src/utils/themedPreview'; interface LibraryStats { id: string; diff --git a/app/src/router.tsx b/app/src/router.tsx index e1f49bcbb3..bebce66934 100644 --- a/app/src/router.tsx +++ b/app/src/router.tsx @@ -4,11 +4,11 @@ import { createBrowserRouter, Navigate, RouterProvider, useParams } from 'react- import Box from '@mui/material/Box'; import CircularProgress from '@mui/material/CircularProgress'; -import { ErrorBoundary } from './components/ErrorBoundary'; -import { AppDataProvider } from './components/Layout'; -import { RootLayout } from './components/RootLayout'; -import { RouteErrorBoundary } from './components/RouteErrorBoundary'; -import { NotFoundPage } from './pages/NotFoundPage'; +import { ErrorBoundary } from 'src/components/ErrorBoundary'; +import { AppDataProvider } from 'src/components/Layout'; +import { RootLayout } from 'src/components/RootLayout'; +import { RouteErrorBoundary } from 'src/components/RouteErrorBoundary'; +import { NotFoundPage } from 'src/pages/NotFoundPage'; const LazyFallback = () => ( @@ -17,7 +17,10 @@ const LazyFallback = () => ( ); const lazySpec = () => - import('./pages/SpecPage').then(m => ({ Component: m.SpecPage, HydrateFallback: LazyFallback })); + import('src/pages/SpecPage').then(m => ({ + Component: m.SpecPage, + HydrateFallback: LazyFallback, + })); function SpecLanguageRedirect() { const { specId, language } = useParams(); @@ -46,47 +49,49 @@ const router = createBrowserRouter([ children: [ { index: true, - lazy: () => import('./pages/LandingPage').then(m => ({ Component: m.LandingPage })), + lazy: () => import('src/pages/LandingPage').then(m => ({ Component: m.LandingPage })), }, { path: 'plots', - lazy: () => import('./pages/PlotsPage').then(m => ({ Component: m.PlotsPage })), + lazy: () => import('src/pages/PlotsPage').then(m => ({ Component: m.PlotsPage })), }, { path: 'specs', - lazy: () => import('./pages/SpecsListPage').then(m => ({ Component: m.SpecsListPage })), + lazy: () => + import('src/pages/SpecsListPage').then(m => ({ Component: m.SpecsListPage })), }, { path: 'libraries', - lazy: () => import('./pages/LibrariesPage').then(m => ({ Component: m.LibrariesPage })), + lazy: () => + import('src/pages/LibrariesPage').then(m => ({ Component: m.LibrariesPage })), }, { path: 'map', - lazy: () => import('./pages/MapPage').then(m => ({ Component: m.MapPage })), + lazy: () => import('src/pages/MapPage').then(m => ({ Component: m.MapPage })), }, { path: 'palette', - lazy: () => import('./pages/PalettePage').then(m => ({ Component: m.PalettePage })), + lazy: () => import('src/pages/PalettePage').then(m => ({ Component: m.PalettePage })), }, { path: 'about', - lazy: () => import('./pages/AboutPage').then(m => ({ Component: m.AboutPage })), + lazy: () => import('src/pages/AboutPage').then(m => ({ Component: m.AboutPage })), }, { path: 'legal', - lazy: () => import('./pages/LegalPage').then(m => ({ Component: m.LegalPage })), + lazy: () => import('src/pages/LegalPage').then(m => ({ Component: m.LegalPage })), }, { path: 'mcp', - lazy: () => import('./pages/McpPage').then(m => ({ Component: m.McpPage })), + lazy: () => import('src/pages/McpPage').then(m => ({ Component: m.McpPage })), }, { path: 'stats', - lazy: () => import('./pages/StatsPage').then(m => ({ Component: m.StatsPage })), + lazy: () => import('src/pages/StatsPage').then(m => ({ Component: m.StatsPage })), }, { path: 'debug', - lazy: () => import('./pages/DebugPage').then(m => ({ Component: m.DebugPage })), + lazy: () => import('src/pages/DebugPage').then(m => ({ Component: m.DebugPage })), }, { path: ':specId', lazy: lazySpec }, { path: ':specId/:language', element: }, diff --git a/app/src/utils/claudePrompt.test.ts b/app/src/utils/claudePrompt.test.ts index 1f23761f86..8c8247a145 100644 --- a/app/src/utils/claudePrompt.test.ts +++ b/app/src/utils/claudePrompt.test.ts @@ -1,6 +1,6 @@ import { beforeEach, describe, expect, it } from 'vitest'; -import { buildClaudePrompt } from './claudePrompt'; +import { buildClaudePrompt } from 'src/utils/claudePrompt'; describe('buildClaudePrompt', () => { beforeEach(() => { diff --git a/app/src/utils/filters-extended.test.ts b/app/src/utils/filters-extended.test.ts index 7fd4ee7b23..36ff72871a 100644 --- a/app/src/utils/filters-extended.test.ts +++ b/app/src/utils/filters-extended.test.ts @@ -1,7 +1,11 @@ import { describe, expect, it } from 'vitest'; -import type { ActiveFilters, FilterCounts } from '../types'; -import { getAvailableValues, getAvailableValuesForGroup, getSearchResults } from './filters'; +import type { ActiveFilters, FilterCounts } from 'src/types'; +import { + getAvailableValues, + getAvailableValuesForGroup, + getSearchResults, +} from 'src/utils/filters'; const mockFilterCounts: FilterCounts = { lang: { python: 28, r: 0 }, diff --git a/app/src/utils/filters.test.ts b/app/src/utils/filters.test.ts index 000461c4c7..201a4e147c 100644 --- a/app/src/utils/filters.test.ts +++ b/app/src/utils/filters.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; -import type { ActiveFilters, FilterCounts } from '../types'; -import { getSearchResults } from './filters'; +import type { ActiveFilters, FilterCounts } from 'src/types'; +import { getSearchResults } from 'src/utils/filters'; describe('getSearchResults', () => { const mockFilterCounts: FilterCounts = { diff --git a/app/src/utils/filters.ts b/app/src/utils/filters.ts index 40c22a511b..554b901ec3 100644 --- a/app/src/utils/filters.ts +++ b/app/src/utils/filters.ts @@ -4,9 +4,9 @@ * Pure functions extracted for reusability and testing. */ -import type { ActiveFilters, FilterCategory, FilterCounts } from '../types'; -import { FILTER_CATEGORIES } from '../types'; -import { createFuzzySearcher, getMatchType, type MatchType } from './fuzzySearch'; +import type { ActiveFilters, FilterCategory, FilterCounts } from 'src/types'; +import { FILTER_CATEGORIES } from 'src/types'; +import { createFuzzySearcher, getMatchType, type MatchType } from 'src/utils/fuzzySearch'; /** * Get counts for a specific filter category. diff --git a/app/src/utils/fuzzySearch.test.ts b/app/src/utils/fuzzySearch.test.ts index b78adb5b26..010a1dfec5 100644 --- a/app/src/utils/fuzzySearch.test.ts +++ b/app/src/utils/fuzzySearch.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { createFuzzySearcher, getMatchType } from './fuzzySearch'; +import { createFuzzySearcher, getMatchType } from 'src/utils/fuzzySearch'; describe('fuzzySearch', () => { describe('getMatchType', () => { diff --git a/app/src/utils/index.ts b/app/src/utils/index.ts index c237a50e7c..4f559b6ea7 100644 --- a/app/src/utils/index.ts +++ b/app/src/utils/index.ts @@ -2,6 +2,6 @@ * Utility functions for anyplot frontend. */ -export * from './tooltip'; -export * from './filters'; -export * from './fuzzySearch'; +export * from 'src/utils/tooltip'; +export * from 'src/utils/filters'; +export * from 'src/utils/fuzzySearch'; diff --git a/app/src/utils/responsiveImage.test.ts b/app/src/utils/responsiveImage.test.ts index 558044aeeb..cbc9a67f12 100644 --- a/app/src/utils/responsiveImage.test.ts +++ b/app/src/utils/responsiveImage.test.ts @@ -8,7 +8,7 @@ import { getResponsiveSizes, OVERVIEW_SIZES, SPECS_SIZES, -} from './responsiveImage'; +} from 'src/utils/responsiveImage'; describe('responsiveImage utilities', () => { const baseUrl = 'https://cdn.example.com/plots/scatter-basic/matplotlib/plot.png'; diff --git a/app/src/utils/responsiveImage.ts b/app/src/utils/responsiveImage.ts index d14019ac14..5ad06091d9 100644 --- a/app/src/utils/responsiveImage.ts +++ b/app/src/utils/responsiveImage.ts @@ -8,7 +8,7 @@ * Principle: always prefer slightly too large over too small (never pixelated). */ -import type { ImageSize } from '../constants'; +import type { ImageSize } from 'src/constants'; const RESPONSIVE_SIZES = [400, 800, 1200] as const; diff --git a/app/src/utils/shuffle.test.ts b/app/src/utils/shuffle.test.ts index 631903fd88..b271633113 100644 --- a/app/src/utils/shuffle.test.ts +++ b/app/src/utils/shuffle.test.ts @@ -7,7 +7,7 @@ import { describe, expect, it, vi } from 'vitest'; -import { shuffleArray } from './shuffle'; +import { shuffleArray } from 'src/utils/shuffle'; describe('shuffleArray', () => { it('returns an array of the same length', () => { diff --git a/app/src/utils/themedPreview.ts b/app/src/utils/themedPreview.ts index 962bce38f3..77d8b3cc63 100644 --- a/app/src/utils/themedPreview.ts +++ b/app/src/utils/themedPreview.ts @@ -13,7 +13,7 @@ * theme and fall back to the legacy field during the transition. */ -import { useTheme } from '../hooks/useLayoutContext'; +import { useTheme } from 'src/hooks/useLayoutContext'; /** Shape accepted by {@link selectPreviewUrl} — covers Implementation + PlotImage + POTD */ export interface ThemedPreviewSource { diff --git a/app/src/utils/tooltip.test.ts b/app/src/utils/tooltip.test.ts index 9f10025df0..e01c77e5d2 100644 --- a/app/src/utils/tooltip.test.ts +++ b/app/src/utils/tooltip.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { createTooltipId, isTooltipOpen, parseTooltipId } from './tooltip'; +import { createTooltipId, isTooltipOpen, parseTooltipId } from 'src/utils/tooltip'; describe('createTooltipId', () => { it('creates spec tooltip ID', () => { diff --git a/app/tsconfig.json b/app/tsconfig.json index 3be25c3d3e..66a9925086 100644 --- a/app/tsconfig.json +++ b/app/tsconfig.json @@ -5,6 +5,9 @@ "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, + "paths": { + "src/*": ["./src/*"] + }, /* Bundler mode */ "moduleResolution": "bundler", diff --git a/app/vite.config.ts b/app/vite.config.ts index cf7a8732dd..8425a54075 100644 --- a/app/vite.config.ts +++ b/app/vite.config.ts @@ -1,9 +1,16 @@ +import { fileURLToPath } from 'node:url'; + import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react-swc'; import { checker } from 'vite-plugin-checker'; import { compression } from 'vite-plugin-compression2'; export default defineConfig({ + resolve: { + alias: { + src: fileURLToPath(new URL('./src', import.meta.url)), + }, + }, plugins: [ react(), // Dev-only TS + ESLint feedback in the browser overlay; the production diff --git a/app/vitest.config.ts b/app/vitest.config.ts index c8b1c7be3a..eb6c78d46c 100644 --- a/app/vitest.config.ts +++ b/app/vitest.config.ts @@ -1,6 +1,13 @@ +import { fileURLToPath } from 'node:url'; + import { defineConfig } from 'vitest/config'; export default defineConfig({ + resolve: { + alias: { + src: fileURLToPath(new URL('./src', import.meta.url)), + }, + }, test: { globals: true, environment: 'jsdom',