Skip to content

Instantly share code, notes, and snippets.

@tresorama
Last active February 14, 2023 12:11
Show Gist options
  • Save tresorama/7865f9fc83387bb243fce2eb66aa0abe to your computer and use it in GitHub Desktop.
Save tresorama/7865f9fc83387bb243fce2eb66aa0abe to your computer and use it in GitHub Desktop.
wp-fes-theme-json-script-tailwind
// Here we generate the "theme.json" programmatically
import resolveConfig from "tailwindcss/resolveConfig.js";
import * as tailwindConfig from "../tailwind.config.js";
import * as fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
// Utility - Disk
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const getFilePathFromHere = (relativePath) => path.resolve(__dirname, relativePath);
const writeJsonToDisk = (filePath, json) => { fs.writeFileSync(filePath, JSON.stringify(json, null, 2)); };
// Tailwind Design System Theme
const { theme: tailwindTheme } = resolveConfig(tailwindConfig);
const tailwindColorsAsWordpressThemeJson = (() => {
const colors = [];
// Example of tailwind colors:
/*
{
black: '#000',
white: '#fff',
slate: {
'50': '#f8fafc',
'100': '#f1f5f9',
'200': '#e2e8f0',
'300': '#cbd5e1',
'400': '#94a3b8',
'500': '#64748b',
'600': '#475569',
'700': '#334155',
'800': '#1e293b',
'900': '#0f172a'
},
}
*/
for (const [colorName, colorValue] of Object.entries(tailwindTheme.colors)) {
// not all color has the numbered scale ( black, white, ...)
if (typeof colorValue === 'string') {
colors.push({
slug: colorName,
name: colorName,
color: colorValue,
});
continue;
}
for (const [shade, colorCode] of Object.entries(colorValue)) {
colors.push({
name: `${colorName}.${shade}`,
slug: `${colorName}.${shade}`,
color: colorCode,
});
}
}
return colors;
})();
const tailwindSpacingAsWordpressThemeJson = (() => {
const spacings = [];
// Example of tailwind spacing:
/*
{
"0": "0px",
"1": "0.25rem",
"2": "0.5rem",
"3": "0.75rem",
"4": "1rem",
"5": "1.25rem",
"6": "1.5rem",
"7": "1.75rem",
"8": "2rem",
"9": "2.25rem",
"10": "2.5rem",
"11": "2.75rem",
"12": "3rem",
"14": "3.5rem",
"16": "4rem",
"20": "5rem",
"24": "6rem",
"28": "7rem",
"32": "8rem",
"36": "9rem",
"40": "10rem",
"44": "11rem",
"48": "12rem",
"52": "13rem",
"56": "14rem",
"60": "15rem",
"64": "16rem",
"72": "18rem",
"80": "20rem",
"96": "24rem",
px: "1px",
"0.5": "0.125rem",
"1.5": "0.375rem",
"2.5": "0.625rem",
"3.5": "0.875rem",
}
*/
for (const [spacingName, spacingValue] of Object.entries(tailwindTheme.spacing)) {
// there is no need for 0 value because
// wordpress already injects it
if (spacingName === '0') continue;
// some keys of tailwind contains a dot in the key
// we need to create a better slug or wordpress cannot
// create a working CSS properties
if (spacingName.includes('.')) {
spacings.push({
name: spacingName,
slug: spacingName.replace('.', '_'),
size: spacingValue,
});
continue;
}
spacings.push({
slug: spacingName,
name: spacingName,
size: spacingValue,
});
}
return spacings;
})();
// Create theme tokens as Wordpress FSE theme.json expect
// create the base theme json
const theme = {
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 2,
"title": "Jachi",
"settings": {
"appearanceTools": true,
"color": {
"defaultPalette": false,
"duotone": [
{
"colors": [
"#000000",
"#ffffff"
],
"slug": "default-filter",
"name": "Default filter"
}
],
"palette": [
// refernce
// ...[
// {
// "color": "#fdff85",
// "name": "Base",
// "slug": "base"
// },
// {
// "color": "#000000",
// "name": "Contrast",
// "slug": "contrast"
// },
// {
// "color": "#000000",
// "name": "Primary",
// "slug": "primary"
// },
// {
// "color": "#353535",
// "name": "Secondary",
// "slug": "secondary"
// },
// {
// "color": "#ffffff",
// "name": "Tertiary",
// "slug": "tertiary"
// }
// ],
// used semantic
...[
{
// used as bgPrimary
"color": tailwindTheme.colors.red['500'],
"name": "Base",
"slug": "base",
},
{
// used as textPrimary
"color": "#000000",
"name": "Contrast",
"slug": "contrast"
},
{
"color": "#000000",
"name": "Primary",
"slug": "primary"
},
{
"color": "#353535",
"name": "Secondary",
"slug": "secondary"
},
{
"color": "#ffffff",
"name": "Tertiary",
"slug": "tertiary"
}
],
// tailwind theme base colors
...tailwindColorsAsWordpressThemeJson,
],
},
"spacing": {
"blockGap": true,
"customSpacingSize": true,
"spacingSizes": [
// reference
// ...[
// {
// "name": "",
// "slug": ""
// "size": "",
// }
// ],
// tailwind theme base spacing scale
...tailwindSpacingAsWordpressThemeJson
]
},
"layout": {
"contentSize": "650px",
"wideSize": "1200px"
},
"typography": {
"fontSizes": [
{
"size": "0.75rem",
"slug": "small"
},
{
"size": "1.125rem",
"slug": "medium"
},
{
"size": "1.75rem",
"slug": "large"
},
{
"size": "2.25rem",
"slug": "x-large"
},
{
"size": "10rem",
"slug": "xx-large"
}
]
},
},
"styles": {
"spacing": {
"blockGap": "0px",
"padding": {
"top": "0px",
"bottom": "0px",
"right": "0px",
"left": "0px"
}
},
"blocks": {
"core/comments": {
"elements": {
"link": {
"typography": {
"textDecoration": "underline"
},
":hover": {
"typography": {
"textDecoration": "none"
}
}
}
}
},
"core/comment-reply-link": {
"typography": {
"fontSize": "var(--wp--preset--font-size--small)"
}
},
"core/comments-title": {
"typography": {
"fontSize": "var(--wp--preset--font-size--small)"
}
},
"core/image": {
"border": {
"radius": "100px 0 0 0"
},
"filter": {
"duotone": "var(--wp--preset--duotone--default-filter)"
}
},
"core/media-text": {
"spacing": {
"blockGap": "var(--wp--preset--spacing--6)"
},
},
"core/navigation": {
"spacing": {
"blockGap": "var(--wp--preset--spacing--6)"
},
"typography": {
"textTransform": "lowercase"
}
},
"core/post-content": {
"elements": {
"link": {
"typography": {
"textDecoration": "underline"
},
":hover": {
"typography": {
"textDecoration": "none"
}
}
}
}
},
"core/post-excerpt": {
"typography": {
"fontSize": "var(--wp--preset--font-size--small)"
}
},
"core/post-featured-image": {
"border": {
"radius": "100px 0 0 0"
},
"spacing": {
"margin": {
"bottom": "0px",
"left": "0px",
"right": "0px",
"top": "0px"
},
"padding": {
"bottom": "0px",
"left": "0px",
"right": "0px",
"top": "0px"
}
}
},
"core/post-title": {
"typography": {
"fontWeight": "700"
}
},
"core/separator": {
"border": {
"width": "2px"
}
},
"core/site-title": {
"typography": {
"fontWeight": "700",
"textTransform": "lowercase",
"fontSize": "var(--wp--preset--font-size--small)"
}
}
},
"elements": {
"button": {
":hover": {
"color": {
"background": "var(--wp--preset--color--base)",
"text": "var(--wp--preset--color--contrast)"
},
"border": {
"color": "var(--wp--preset--color--contrast)",
"style": "solid",
"width": "2px"
}
},
":focus": {
"color": {
"background": "var(--wp--preset--color--base)",
"text": "var(--wp--preset--color--contrast)"
},
"border": {
"color": "var(--wp--preset--color--contrast)",
"style": "solid",
"width": "2px"
}
},
":visited": {
"color": {
"text": "var(--wp--preset--color--base)"
}
},
"border": {
"radius": "5px",
"color": "var(--wp--preset--color--contrast)",
"style": "solid",
"width": "2px"
},
"color": {
"text": "var(--wp--preset--color--base)"
},
"spacing": {
"padding": {
"bottom": "0.667em",
"left": "1.333em",
"right": "1.333em",
"top": "0.667em"
}
}
},
"h1": {
"typography": {
"fontSize": "var(--wp--preset--font-size--small)"
}
},
"h2": {
"typography": {
"fontSize": "var(--wp--preset--font-size--small)"
}
},
"h3": {
"typography": {
"fontSize": "var(--wp--preset--font-size--small)"
}
},
"h4": {
"typography": {
"fontSize": "var(--wp--preset--font-size--small)"
}
},
"heading": {
"typography": {
"fontWeight": "700"
}
},
"link": {
"typography": {
"textDecoration": "none"
}
}
},
"typography": {
"fontFamily": "var(--wp--preset--font-family--ibm-plex-mono)",
"fontSize": "var(--wp--preset--font-size--small)"
}
}
};
// output
writeJsonToDisk(
getFilePathFromHere('./jachi.json'),
theme,
);
{
"private": true,
"name": "twentytwentythree-custom",
"version": "1.0.0",
"main": "index.js",
"author": "Jacopo Marrone <@tresorama> <jacopo.marrone27@gmail.com> (https://github.com/tresorama)",
"license": "MIT",
"type": "commonjs",
"devDependencies": {
"tailwindcss": "^3.2.6"
}
}
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [],
theme: {
extend: {},
},
plugins: [],
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment