diff --git a/e2e/sign-in-button.spec.ts b/e2e/sign-in-button.spec.ts index b3e1403..6ca0b30 100644 --- a/e2e/sign-in-button.spec.ts +++ b/e2e/sign-in-button.spec.ts @@ -1,5 +1,7 @@ import { expect, test } from '@playwright/test'; +const HEADER_SNAPSHOT_MAX_DIFF_PIXELS = 250; + test.describe('Sign in button', () => { test('renders without issue', async ({ page }) => { await page.goto('/'); @@ -13,6 +15,8 @@ test.describe('Sign in button', () => { const header = page.locator('header').first(); await expect(header).toBeVisible(); - await expect(header).toHaveScreenshot('header-sign-in.png'); + await expect(header).toHaveScreenshot('header-sign-in.png', { + maxDiffPixels: HEADER_SNAPSHOT_MAX_DIFF_PIXELS, + }); }); }); diff --git a/public/assets/library-icons/stylex.svg b/public/assets/library-icons/stylex.svg new file mode 100644 index 0000000..34f3a7b --- /dev/null +++ b/public/assets/library-icons/stylex.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/lib/ingest/loaders/libraries.ts b/src/lib/ingest/loaders/libraries.ts index a042d55..09bd906 100644 --- a/src/lib/ingest/loaders/libraries.ts +++ b/src/lib/ingest/loaders/libraries.ts @@ -97,9 +97,10 @@ export class LibrariesLoader implements ContentLoader { // Data Tables (1 repository) { repo: 'TanStack/table', name: 'TanStack Table', category: 'Data Tables', tier: 'Tier 1' }, - // Styling (2 repositories) + // Styling (3 repositories) { repo: 'styled-components/styled-components', name: 'styled-components', category: 'Styling', tier: 'Tier 1' }, { repo: 'emotion-js/emotion', name: 'Emotion', category: 'Styling', tier: 'Tier 1' }, + { repo: 'facebook/stylex', name: 'StyleX', category: 'Styling', tier: 'Tier 2' }, ]; async load(): Promise { diff --git a/src/lib/library-icons.tsx b/src/lib/library-icons.tsx index 4123e1b..3ddc657 100644 --- a/src/lib/library-icons.tsx +++ b/src/lib/library-icons.tsx @@ -1,8 +1,9 @@ /** - * Icon mapping for all 55 React ecosystem libraries + * Icon mapping for all 56 React ecosystem libraries * Uses Simple Icons via @icons-pack/react-simple-icons */ +import Image from "next/image"; import { SiReact, SiRedux, @@ -38,6 +39,18 @@ import { // Simple Icons doesn't have all libraries, so we'll use fallback for missing ones type IconComponent = React.ComponentType<{ size?: number; color?: string; className?: string }>; +function StylexIcon({ size = 20, className }: { size?: number; color?: string; className?: string }) { + return ( + StyleX logo + ); +} + // Icon mapping by library repo name export const libraryIcons: Record = { // Core React @@ -121,6 +134,7 @@ export const libraryIcons: Record = { "styled-components": SiStyledcomponents, emotion: null, tailwindcss: SiTailwindcss, + stylex: StylexIcon, nativewind: SiTailwindcss, // Use Tailwind logo for NativeWind }; @@ -184,6 +198,7 @@ export const libraryDisplayNames: Record = { "styled-components": "Styled Components", emotion: "Emotion", tailwindcss: "Tailwind CSS", + stylex: "StyleX", nativewind: "NativeWind", }; diff --git a/src/lib/maintainer-tiers.test.ts b/src/lib/maintainer-tiers.test.ts index 0d8eeeb..f5b6dc0 100644 --- a/src/lib/maintainer-tiers.test.ts +++ b/src/lib/maintainer-tiers.test.ts @@ -1,6 +1,8 @@ +import { createElement } from 'react'; +import { renderToStaticMarkup } from 'react-dom/server'; import { describe, expect, it } from 'vitest'; -import { libraryDisplayNames } from './library-icons'; +import { LibraryIcon, libraryDisplayNames } from './library-icons'; import { ecosystemLibraries } from './maintainer-tiers'; import { LibrariesLoader } from './ingest/loaders/libraries'; import { NPMCollector } from './ris/collectors/npm-collector'; @@ -60,4 +62,35 @@ describe('ecosystemLibraries', () => { }) ); }); + + it('includes StyleX in related library datasets', async () => { + expect(findLibrary('facebook', 'stylex')).toMatchObject({ + category: 'styling', + tier: 2, + }); + expect(NPMCollector.getPackageName('facebook', 'stylex')).toBe('@stylexjs/stylex'); + expect(libraryDisplayNames.stylex).toBe('StyleX'); + + const stylexIconMarkup = renderToStaticMarkup( + createElement(LibraryIcon, { libraryName: 'stylex', size: 24 }) + ); + expect(stylexIconMarkup).toContain('/assets/library-icons/stylex.svg'); + + expect(PROBE_REPOS).toContainEqual( + expect.objectContaining({ + owner: 'facebook', + repo: 'stylex', + category: 'ui-library', + }) + ); + + const loader = new LibrariesLoader(); + const records = await loader.load(); + expect(records).toContainEqual( + expect.objectContaining({ + id: 'library-facebook-stylex', + title: 'StyleX', + }) + ); + }); }); diff --git a/src/lib/maintainer-tiers.ts b/src/lib/maintainer-tiers.ts index 5d4d552..83c1ebe 100644 --- a/src/lib/maintainer-tiers.ts +++ b/src/lib/maintainer-tiers.ts @@ -125,10 +125,11 @@ export const ecosystemLibraries: RepoTarget[] = [ // Data Tables (1 repo) { owner: "TanStack", name: "table", category: "tables", tier: 1 }, - // Styling (4 repos) + // Styling (5 repos) { owner: "styled-components", name: "styled-components", category: "styling", tier: 1 }, { owner: "emotion-js", name: "emotion", category: "styling", tier: 1 }, { owner: "tailwindlabs", name: "tailwindcss", category: "styling", tier: 1 }, + { owner: "facebook", name: "stylex", category: "styling", tier: 2 }, { owner: "marklawlor", name: "nativewind", category: "styling", tier: 2 }, ]; diff --git a/src/lib/ris/collectors/npm-collector.ts b/src/lib/ris/collectors/npm-collector.ts index b582e12..d22ab1d 100644 --- a/src/lib/ris/collectors/npm-collector.ts +++ b/src/lib/ris/collectors/npm-collector.ts @@ -177,6 +177,7 @@ export class NPMCollector { 'facebook/hermes': null, // JavaScript engine (C++ binary, not on NPM) 'facebook/metro': 'metro', 'facebook/react-devtools': 'react-devtools', + 'facebook/stylex': '@stylexjs/stylex', 'reactjs/react.dev': null, // Documentation website (not a library) 'reactjs/rfcs': null, // RFC repository (not a library) 'reduxjs/redux': 'redux', diff --git a/src/lib/ris/data/probe-repos.ts b/src/lib/ris/data/probe-repos.ts index a9f43ca..53334d3 100644 --- a/src/lib/ris/data/probe-repos.ts +++ b/src/lib/ris/data/probe-repos.ts @@ -36,6 +36,7 @@ export const PROBE_REPOS: ProbeRepo[] = [ { owner: 'radix-ui', repo: 'primitives', stars: 16000, category: 'ui-library', description: 'Radix Primitives' }, { owner: 'adobe', repo: 'react-spectrum', stars: 13000, category: 'ui-library', description: 'React Spectrum' }, { owner: 'tailwindlabs', repo: 'headlessui', stars: 26000, category: 'ui-library', description: 'Headless UI' }, + { owner: 'facebook', repo: 'stylex', stars: 8000, category: 'ui-library', description: 'StyleX styling system' }, { owner: 'ariakit', repo: 'ariakit', stars: 8000, category: 'ui-library', description: 'Ariakit' }, { owner: 'mantine-dev', repo: 'mantine', stars: 27000, category: 'ui-library', description: 'Mantine' }, { owner: 'palantir', repo: 'blueprint', stars: 21000, category: 'ui-library', description: 'Blueprint' },