Skip to content

Commit

Permalink
re-think theme.json generation
Browse files Browse the repository at this point in the history
  • Loading branch information
retlehs committed Dec 28, 2024
1 parent dbd8dc4 commit 8278093
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 87 deletions.
2 changes: 1 addition & 1 deletion app/setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
*/
add_filter('theme_file_path', function (string $path, string $file): string {
if ($file === 'theme.json') {
return public_path().'/build/theme.json';
return public_path().'/build/assets/theme.json';
}

return $path;
Expand Down
128 changes: 70 additions & 58 deletions resources/js/build/wordpress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
defaultRequestToExternal,
defaultRequestToHandle,
} from '@wordpress/dependency-extraction-webpack-plugin/lib/util'
import fs from 'fs'
import path from 'path'

// Theme JSON Types
interface ThemeJsonColor {
Expand Down Expand Up @@ -265,73 +267,83 @@ export function wordpressRollupPlugin(): Plugin {
}
}

export function wordpressThemeJson(options: ThemeJsonOptions = {}): Plugin {
const defaultSettings: ThemeJsonSettings = {
background: { backgroundImage: true },
color: {
custom: false,
customDuotone: false,
customGradient: false,
defaultDuotone: false,
defaultGradients: false,
defaultPalette: false,
duotone: [],
},
custom: {
spacing: {},
typography: { 'font-size': {}, 'line-height': {} },
},
spacing: { padding: true, units: ['px', '%', 'em', 'rem', 'vw', 'vh'] },
typography: { customFontSize: false },
}
function flattenColors(colors: Record<string, any>, prefix = '') {
return Object.entries(colors).reduce((acc, [name, value]) => {
const formattedName = name.charAt(0).toUpperCase() + name.slice(1)

if (typeof value === 'string') {
acc.push({
name: prefix ? `${prefix.charAt(0).toUpperCase() + prefix.slice(1)}-${formattedName}` : formattedName,
slug: prefix ? `${prefix}-${name}`.toLowerCase() : name.toLowerCase(),
color: value,
})
} else if (typeof value === 'object') {
acc.push(...flattenColors(value, name))
}
return acc
}, [] as Array<{ name: string; slug: string; color: string }>)
}

const mergedSettings = mergeSettings(defaultSettings, options.settings)
export function wordpressThemeJson({
tailwindConfig,
disableColors = false,
disableFonts = false,
disableFontSizes = false,
}) {
const resolvedConfig = resolveConfig(tailwindConfig)

return {
name: 'wordpress-theme-json',
generateBundle() {
const themeJson: Record<string, any> = {
__generated__: '⚠️ This file is generated. Do not edit.',
$schema: 'https://schemas.wp.org/trunk/theme.json',
version: options.version ?? 3,
settings: mergedSettings,
}

if (options.tailwindConfig) {
const tailwindConfig = options.tailwindConfig

if (!options.disableColors) {
themeJson.settings.color = {
...(themeJson.settings.color || {}),
palette: convertTailwindColorsToThemeJson(tailwindConfig),
}
}

if (!options.disableFonts) {
themeJson.settings.typography = {
...(themeJson.settings.typography || {}),
fontFamilies: convertTailwindFontFamiliesToThemeJson(tailwindConfig),
}
}

if (!options.disableFontSizes) {
themeJson.settings.typography = {
...(themeJson.settings.typography || {}),
fontSizes: convertTailwindFontSizesToThemeJson(tailwindConfig),
}
}
async generateBundle() {
const baseThemeJson = JSON.parse(
fs.readFileSync(path.resolve('./theme.json'), 'utf8')
)

const themeJson = {
__processed__: "This file was generated from the Vite build",
...baseThemeJson,
settings: {
...baseThemeJson.settings,
...((!disableColors && resolvedConfig.theme?.colors && {
color: {
...baseThemeJson.settings?.color,
palette: flattenColors(resolvedConfig.theme.colors),
},
}) ||
{}),
...((!disableFonts && resolvedConfig.theme?.fontFamily && {
typography: {
...baseThemeJson.settings?.typography,
fontFamilies: Object.entries(resolvedConfig.theme.fontFamily)
.map(([name, value]) => ({
name,
slug: name,
fontFamily: Array.isArray(value) ? value.join(',') : value,
})),
},
}) ||
{}),
...((!disableFontSizes && resolvedConfig.theme?.fontSize && {
typography: {
...baseThemeJson.settings?.typography,
fontSizes: Object.entries(resolvedConfig.theme.fontSize)
.map(([name, value]) => ({
name,
slug: name,
size: Array.isArray(value) ? value[0] : value,
})),
},
}) ||
{}),
},
}

if (options.customTemplates) themeJson.customTemplates = options.customTemplates
if (options.patterns) themeJson.patterns = options.patterns
if (options.styles) themeJson.styles = options.styles
if (options.templateParts) themeJson.templateParts = options.templateParts
if (options.title) themeJson.title = options.title
delete themeJson.__preprocessed__

this.emitFile({
type: 'asset',
fileName: options.fileName || 'theme.json',
source: JSON.stringify(themeJson, null, 2),
fileName: 'assets/theme.json',
source: JSON.stringify(themeJson, null, 2)
})
},
}
Expand Down
34 changes: 34 additions & 0 deletions theme.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"__preprocessed__": "This file is used to build the theme.json file in the `public/build/assets` directory. The built artifact includes Tailwind's colors, fonts, and font sizes.",
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"background": {
"backgroundImage": true
},
"color": {
"custom": false,
"customDuotone": false,
"customGradient": false,
"defaultDuotone": false,
"defaultGradients": false,
"defaultPalette": false,
"duotone": []
},
"custom": {
"spacing": {},
"typography": {
"font-size": {},
"line-height": {}
}
},
"spacing": {
"padding": true,
"units": ["px", "%", "em", "rem", "vw", "vh"]
},
"typography": {
"defaultFontSizes": false,
"customFontSize": false
}
}
}
32 changes: 4 additions & 28 deletions vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,14 @@ export default defineConfig({
],
refresh: true,
}),

wordpressPlugin(),
wordpressRollupPlugin(),

// Generate the theme.json file in the public/build/assets directory
// based on the Tailwind config and the theme.json file from base theme folder
wordpressThemeJson({
tailwindConfig,
settings: {
background: {
backgroundImage: true,
},
color: {
custom: false,
customDuotone: false,
customGradient: false,
defaultDuotone: false,
defaultGradients: false,
defaultPalette: false,
duotone: [],
},
custom: {
spacing: {},
typography: {
'font-size': {},
'line-height': {},
},
},
spacing: {
padding: true,
units: ['px', '%', 'em', 'rem', 'vw', 'vh'],
},
typography: {
customFontSize: false,
},
},
disableColors: false,
disableFonts: false,
disableFontSizes: false,
Expand Down

0 comments on commit 8278093

Please sign in to comment.