Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

strategy:
matrix:
node-version: [18.x, 20.x, 22.x, latest]
node-version: [20.x, 22.x, latest]

steps:
- name: Checkout code
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
"esbuild": "0.25.6",
"eslint": "^9.0.0",
"globals": "^16.3.0",
"@tailwindcss/oxide": "^4.1.11",
"@tailwindcss/vite": "^4.1.11",
"tailwindcss": "^4.1.11",
"typescript": "^5.0.0",
"vite": "^7.0.0",
Expand Down
8 changes: 4 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1164,13 +1164,13 @@ export function wordpressThemeJson(config: ThemeJsonConfig = {}): VitePlugin {
};

const patterns = {
COLOR: /(?:^|[;{}])\s*--color-([^:]+):\s*([^;}]+)[;}]?/gm,
COLOR: /(?:^|[;{}])\s*--color-([^:]+):\s*([^;}]+)/gm,
FONT_FAMILY:
/(?:^|[;{}])\s*--font-([^:]+):\s*([^;}]+)[;}]?/gm,
/(?:^|[;{}])\s*--font-([^:]+):\s*([^;}]+)/gm,
FONT_SIZE:
/(?:^|[;{}])\s*--text-([^:]+):\s*([^;}]+)[;}]?/gm,
/(?:^|[;{}])\s*--text-([^:]+):\s*([^;}]+)/gm,
BORDER_RADIUS:
/(?:^|[;{}])\s*--radius-([^:]+):\s*([^;}]+)[;}]?/gm,
/(?:^|[;{}])\s*--radius-([^:]+):\s*([^;}]+)/gm,
} as const;

// Process colors from either @theme block or Tailwind config
Expand Down
120 changes: 120 additions & 0 deletions tests/build.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { describe, expect, it, afterAll } from 'vitest';
import { build } from 'vite';
import tailwindcss from '@tailwindcss/vite';
import { wordpressThemeJson } from '../src/index.js';
import fs from 'fs';
import path from 'path';

const fixtureDir = path.resolve(__dirname, 'fixture');
const outDir = path.join(fixtureDir, 'dist');

async function runBuild(pluginOptions = {}) {
await build({
plugins: [
tailwindcss(),
wordpressThemeJson({
baseThemeJsonPath: path.join(fixtureDir, 'theme.json'),
outputPath: 'theme.json',
...pluginOptions,
}),
],
build: {
rollupOptions: {
input: path.join(fixtureDir, 'app.css'),
},
outDir,
emptyOutDir: true,
write: true,
},
logLevel: 'silent',
});

return JSON.parse(fs.readFileSync(path.join(outDir, 'theme.json'), 'utf8'));
}

describe('vite build integration', () => {
afterAll(() => {
fs.rmSync(outDir, { recursive: true, force: true });
});

describe('colors', () => {
it('should extract all 11 shades for each color', async () => {
const themeJson = await runBuild();
const palette = themeJson.settings.color.palette;

const redColors = palette.filter((c: any) => c.slug.startsWith('red-'));
expect(redColors).toHaveLength(11);

const expectedShades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
for (const shade of expectedShades) {
expect(palette).toContainEqual(
expect.objectContaining({
name: `Red (${shade})`,
slug: `red-${shade}`,
})
);
}
});

it('should include all Tailwind color families', async () => {
const themeJson = await runBuild();
const palette = themeJson.settings.color.palette;
const slugs = palette.map((c: any) => c.slug);

const expectedFamilies = [
'red', 'orange', 'amber', 'yellow', 'lime', 'green',
'emerald', 'teal', 'cyan', 'sky', 'blue', 'indigo',
'violet', 'purple', 'fuchsia', 'pink', 'rose',
'slate', 'gray', 'zinc', 'neutral', 'stone',
];

for (const family of expectedFamilies) {
expect(slugs.some((s: string) => s.startsWith(`${family}-`))).toBe(true);
}
});

it('should not include colors when disabled', async () => {
const themeJson = await runBuild({ disableTailwindColors: true });
expect(themeJson.settings.color.palette).toBeUndefined();
});
});

describe('fonts', () => {
it('should extract font families', async () => {
const themeJson = await runBuild();
const fonts = themeJson.settings.typography.fontFamilies;

expect(fonts).toContainEqual(
expect.objectContaining({ slug: 'sans' })
);
expect(fonts).toContainEqual(
expect.objectContaining({ slug: 'mono' })
);
});
});

describe('font sizes', () => {
it('should extract all font sizes', async () => {
const themeJson = await runBuild();
const sizes = themeJson.settings.typography.fontSizes;

const expectedSizes = ['xs', 'sm', 'base', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl', '6xl', '7xl', '8xl', '9xl'];
for (const size of expectedSizes) {
expect(sizes).toContainEqual(
expect.objectContaining({ slug: size })
);
}
});
});

describe('border radius', () => {
it('should extract border radius sizes', async () => {
const themeJson = await runBuild({ disableTailwindBorderRadius: false });
const radiusSizes = themeJson.settings.border?.radiusSizes;

expect(radiusSizes).toBeDefined();
expect(radiusSizes!.length).toBeGreaterThan(0);
});
});
});
1 change: 1 addition & 0 deletions tests/fixture/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "tailwindcss" theme(static);
14 changes: 14 additions & 0 deletions tests/fixture/theme.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"color": {
"custom": false,
"defaultPalette": false
},
"typography": {
"defaultFontSizes": false,
"customFontSize": false
}
}
}
Loading