Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
"react": "^19.3.1",
"react-dom": "^19.3.1",
"react-force-graph-2d": "^1.29.2",
"react-helmet-async": "^3.0.0",
"react-router-dom": "^7.18.4",
"react-syntax-highlighter": "^16.1.2",
"web-vitals": "^6.2.3"
Expand Down
4 changes: 0 additions & 4 deletions app/src/components/RouteErrorBoundary.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ import { createTheme, ThemeProvider } from '@mui/material/styles';

import { RouteErrorBoundary } from 'src/components/RouteErrorBoundary';

vi.mock('react-helmet-async', () => ({
Helmet: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}));

const theme = createTheme();

function renderWithRouter(thrown: unknown) {
Expand Down
3 changes: 0 additions & 3 deletions app/src/hooks/useUrlSync.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,12 @@ describe('useUrlSync', () => {
renderHook(() => useUrlSync({ activeFilters: filters, onTrackPageview }));

expect(window.location.search).toBe('?lib=matplotlib');
expect(document.title).toBe('lib:matplotlib | anyplot.ai');
expect(onTrackPageview).toHaveBeenCalled();
});

it('sets default title for no filters', () => {
const onTrackPageview = vi.fn();

renderHook(() => useUrlSync({ activeFilters: [], onTrackPageview }));

expect(document.title).toBe('anyplot.ai');
});
});
2 changes: 0 additions & 2 deletions app/src/hooks/useUrlSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ export function useUrlSync({ activeFilters, onTrackPageview }: UseUrlSyncOptions
useEffect(() => {
const newUrl = buildFilterUrl(activeFilters);
window.history.replaceState({}, '', newUrl);

// Update document title
const filterParts = activeFilters
.filter(f => f.values.length > 0)
.map(f => `${f.category}:${f.values.join(',')}`)
Expand Down
25 changes: 11 additions & 14 deletions app/src/pages/AboutPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useEffect } from 'react';

import { Helmet } from 'react-helmet-async';
import { Link as RouterLink } from 'react-router-dom';

import Box from '@mui/material/Box';
Expand Down Expand Up @@ -50,19 +49,17 @@ export function AboutPage() {

return (
<>
<Helmet>
<title>about | anyplot.ai</title>
<meta
name="description"
content="a catalogue of plotting examples across fifteen libraries in python, r, julia, and javascript. plot ideas come from humans; ai drafts the spec, generates code for every library, and reviews each implementation."
/>
<meta property="og:title" content="about | anyplot.ai" />
<meta
property="og:description"
content="humans submit ideas. ai drafts specs, generates code, reviews. humans approve."
/>
<link rel="canonical" href="https://anyplot.ai/about" />
</Helmet>
<title>about | anyplot.ai</title>
<meta
name="description"
content="a catalogue of plotting examples across fifteen libraries in python, r, julia, and javascript. plot ideas come from humans; ai drafts the spec, generates code for every library, and reviews each implementation."
/>
<meta property="og:title" content="about | anyplot.ai" />
<meta
property="og:description"
content="humans submit ideas. ai drafts specs, generates code, reviews. humans approve."
/>
<link rel="canonical" href="https://anyplot.ai/about" />

<Box sx={{ pb: 4 }}>
{/* About (lede) */}
Expand Down
4 changes: 0 additions & 4 deletions app/src/pages/AgentChatPage.feedback.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ vi.mock('src/global-config', async importOriginal => {
};
});

vi.mock('react-helmet-async', () => ({
Helmet: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}));

const analytics = vi.hoisted(() => ({ trackEvent: vi.fn(), trackPageview: vi.fn() }));
vi.mock('src/hooks/useAnalytics', () => ({ useAnalytics: () => analytics }));

Expand Down
4 changes: 0 additions & 4 deletions app/src/pages/AgentChatPage.language.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ vi.mock('src/global-config', async importOriginal => {
};
});

vi.mock('react-helmet-async', () => ({
Helmet: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}));

const analytics = vi.hoisted(() => ({ trackEvent: vi.fn(), trackPageview: vi.fn() }));
vi.mock('src/hooks/useAnalytics', () => ({ useAnalytics: () => analytics }));

Expand Down
4 changes: 0 additions & 4 deletions app/src/pages/AgentChatPage.save.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ vi.mock('src/global-config', async importOriginal => {
};
});

vi.mock('react-helmet-async', () => ({
Helmet: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}));

const analytics = vi.hoisted(() => ({ trackEvent: vi.fn(), trackPageview: vi.fn() }));
vi.mock('src/hooks/useAnalytics', () => ({ useAnalytics: () => analytics }));

Expand Down
4 changes: 0 additions & 4 deletions app/src/pages/AgentChatPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ vi.mock('src/global-config', async importOriginal => {
};
});

vi.mock('react-helmet-async', () => ({
Helmet: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}));

// Stable identities, like the real hook (effects depend on them).
const analytics = vi.hoisted(() => ({ trackEvent: vi.fn(), trackPageview: vi.fn() }));
vi.mock('src/hooks/useAnalytics', () => ({ useAnalytics: () => analytics }));
Expand Down
8 changes: 3 additions & 5 deletions app/src/pages/AgentChatPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@

import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';

import { Helmet } from 'react-helmet-async';
import { Link as RouterLink, useSearchParams } from 'react-router-dom';

import Box from '@mui/material/Box';
Expand Down Expand Up @@ -525,10 +524,9 @@ function AgentChat({ specId, library, language, token, onLibraryChange }: AgentC

return (
<>
<Helmet>
<title>{`agent · ${specId} | anyplot.ai`}</title>
<meta name="robots" content="noindex, nofollow" />
</Helmet>
<title>{`agent · ${specId} | anyplot.ai`}</title>
<meta name="robots" content="noindex, nofollow" />

{/* `colorScheme` gives the native controls (scrollbars, select menus) the site theme. */}
<Box
sx={{
Expand Down
6 changes: 0 additions & 6 deletions app/src/pages/LandingPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,6 @@ vi.mock('src/sections/landing/NumbersStrip', () => ({
NumbersStrip: () => <div data-testid="numbers" />,
}));

vi.mock('react-helmet-async', () => ({
Helmet: ({ children }: { children: React.ReactNode }) => (
<div data-testid="helmet">{children}</div>
),
}));

import { LandingPage } from 'src/pages/LandingPage';

describe('LandingPage', () => {
Expand Down
15 changes: 6 additions & 9 deletions app/src/pages/LandingPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useEffect, useState } from 'react';

import { Helmet } from 'react-helmet-async';
import { Link as RouterLink, useNavigate } from 'react-router-dom';

import Box from '@mui/material/Box';
Expand Down Expand Up @@ -37,14 +36,12 @@ export function LandingPage() {

return (
<>
<Helmet>
<title>any.plot() — any library.</title>
<meta
name="description"
content="any library. get inspired. grab the code. make it yours. human ideas, ai builds the rest. 15 plotting libraries across python, r, julia & javascript, colorblind-safe, open source."
/>
<link rel="canonical" href="https://anyplot.ai/" />
</Helmet>
<title>any.plot() — any library.</title>
<meta
name="description"
content="any library. get inspired. grab the code. make it yours. human ideas, ai builds the rest. 15 plotting libraries across python, r, julia & javascript, colorblind-safe, open source."
/>
<link rel="canonical" href="https://anyplot.ai/" />

{/* Hero — fills the viewport so the fold shows only the hero */}
<Box
Expand Down
4 changes: 0 additions & 4 deletions app/src/pages/LegalPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ import { describe, expect, it, vi } from 'vitest';
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('src/hooks', () => ({
useAnalytics: () => ({
Expand Down
26 changes: 11 additions & 15 deletions app/src/pages/LegalPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { useEffect } from 'react';

import { Helmet } from 'react-helmet-async';

import Box from '@mui/material/Box';
import Link from '@mui/material/Link';
import Table from '@mui/material/Table';
Expand Down Expand Up @@ -136,19 +134,17 @@ export function LegalPage() {

return (
<>
<Helmet>
<title>legal | anyplot.ai</title>
<meta
name="description"
content="legal notice, privacy policy, and transparency information for anyplot.ai"
/>
<meta property="og:title" content="legal | anyplot.ai" />
<meta
property="og:description"
content="legal notice, privacy policy, and transparency information"
/>
<link rel="canonical" href="https://anyplot.ai/legal" />
</Helmet>
<title>legal | anyplot.ai</title>
<meta
name="description"
content="legal notice, privacy policy, and transparency information for anyplot.ai"
/>
<meta property="og:title" content="legal | anyplot.ai" />
<meta
property="og:description"
content="legal notice, privacy policy, and transparency information"
/>
<link rel="canonical" href="https://anyplot.ai/legal" />

<Box sx={{ pb: 4 }}>
{/* Legal Notice */}
Expand Down
6 changes: 0 additions & 6 deletions app/src/pages/LibrariesPage.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import type { ReactNode } from 'react';

import { beforeEach, describe, expect, it, vi } from 'vitest';

import { render, screen, userEvent } from 'src/test-utils';
Expand All @@ -24,10 +22,6 @@ vi.mock('src/hooks', async () => {
};
});

vi.mock('react-helmet-async', () => ({
Helmet: ({ children }: { children: ReactNode }) => <div data-testid="helmet">{children}</div>,
}));

vi.mock('react-router-dom', async () => {
const actual = await vi.importActual<typeof import('react-router-dom')>('react-router-dom');
return { ...actual, useNavigate: () => navigate };
Expand Down
25 changes: 11 additions & 14 deletions app/src/pages/LibrariesPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useEffect, useState } from 'react';

import { Helmet } from 'react-helmet-async';
import { useNavigate } from 'react-router-dom';

import Box from '@mui/material/Box';
Expand Down Expand Up @@ -71,19 +70,17 @@ export function LibrariesPage() {

return (
<>
<Helmet>
<title>libraries | anyplot.ai</title>
<meta
name="description"
content="Fifteen plotting libraries across Python, R, Julia, and JavaScript — matplotlib, seaborn, plotly, bokeh, altair, plotnine, pygal, lets-plot, ggplot2, Makie.jl, Chart.js, D3.js, ECharts, Highcharts, MUI X Charts. Same specs, every library."
/>
<meta property="og:title" content="libraries | anyplot.ai" />
<meta
property="og:description"
content="Fifteen plotting libraries across Python, R, Julia, and JavaScript — same specs, every library."
/>
<link rel="canonical" href="https://anyplot.ai/libraries" />
</Helmet>
<title>libraries | anyplot.ai</title>
<meta
name="description"
content="Fifteen plotting libraries across Python, R, Julia, and JavaScript — matplotlib, seaborn, plotly, bokeh, altair, plotnine, pygal, lets-plot, ggplot2, Makie.jl, Chart.js, D3.js, ECharts, Highcharts, MUI X Charts. Same specs, every library."
/>
<meta property="og:title" content="libraries | anyplot.ai" />
<meta
property="og:description"
content="Fifteen plotting libraries across Python, R, Julia, and JavaScript — same specs, every library."
/>
<link rel="canonical" href="https://anyplot.ai/libraries" />

<Box sx={{ maxWidth: 'var(--max-catalog, 2200px)', mx: 'auto', pt: { xs: 2, md: 3 }, pb: 6 }}>
<SectionHeader prompt="❯" title={<em>libraries</em>} />
Expand Down
4 changes: 0 additions & 4 deletions app/src/pages/MapPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { MapPage } from 'src/pages/MapPage';
import { act, render, screen, waitFor } from 'src/test-utils';

vi.mock('react-helmet-async', () => ({
Helmet: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}));

const mockNavigate = vi.fn();
const mockTrackEvent = vi.fn();

Expand Down
14 changes: 6 additions & 8 deletions app/src/pages/MapPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useEffect, useMemo, useRef, useState } from 'react';

import ForceGraph2D from 'react-force-graph-2d';
import { Helmet } from 'react-helmet-async';
import { Link, useNavigate } from 'react-router-dom';

import Box from '@mui/material/Box';
Expand Down Expand Up @@ -344,13 +343,12 @@ export function MapPage() {

return (
<>
<Helmet>
<title>map() — anyplot</title>
<meta
name="description"
content="Interactive map of all anyplot specifications, clustered by tag similarity."
/>
</Helmet>
<title>map() — anyplot</title>
<meta
name="description"
content="Interactive map of all anyplot specifications, clustered by tag similarity."
/>

<Box
ref={containerRef}
// Negative margins cancel RootLayout's container px so the canvas goes full-bleed.
Expand Down
4 changes: 0 additions & 4 deletions app/src/pages/McpPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ import { describe, expect, it, vi } from 'vitest';
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('src/hooks', () => ({
useAnalytics: () => ({
trackPageview: vi.fn(),
Expand Down
26 changes: 11 additions & 15 deletions app/src/pages/McpPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { useEffect } from 'react';

import { Helmet } from 'react-helmet-async';

import Box from '@mui/material/Box';
import Link from '@mui/material/Link';
import Table from '@mui/material/Table';
Expand Down Expand Up @@ -44,19 +42,17 @@ export function McpPage() {

return (
<>
<Helmet>
<title>mcp | anyplot.ai</title>
<meta
name="description"
content="configure Claude Code to access anyplot data via the Model Context Protocol (MCP) server."
/>
<meta property="og:title" content="mcp | anyplot.ai" />
<meta
property="og:description"
content="configure Claude Code to access anyplot data via MCP"
/>
<link rel="canonical" href="https://anyplot.ai/mcp" />
</Helmet>
<title>mcp | anyplot.ai</title>
<meta
name="description"
content="configure Claude Code to access anyplot data via the Model Context Protocol (MCP) server."
/>
<meta property="og:title" content="mcp | anyplot.ai" />
<meta
property="og:description"
content="configure Claude Code to access anyplot data via MCP"
/>
<link rel="canonical" href="https://anyplot.ai/mcp" />

<Box sx={{ pb: 4 }}>
{/* What is MCP */}
Expand Down
5 changes: 0 additions & 5 deletions app/src/pages/NotFoundPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ import { render, screen } from 'src/test-utils';

const mockTrackEvent = vi.fn();

// Mock react-helmet-async to avoid provider requirement
vi.mock('react-helmet-async', () => ({
Helmet: ({ children }: { children: React.ReactNode }) => <>{children}</>,
}));

vi.mock('src/hooks/useAnalytics', () => ({
useAnalytics: () => ({
trackPageview: vi.fn(),
Expand Down
Loading
Loading