Uno Spettro
Uno Spettro

Reputation: 47

Tailwind CSS: can't import color palettes from JSON

I'm using Tailwind CSS in a Vue.js project and have encountered an issue where Tailwind does not generate custom color classes based on my JSON configuration for 'primary', 'secondary', and 'gray'. Instead of using the 'gray' shades defined in my JSON, Tailwind uses its default 'gray' colors.

Project Structure:

    tailwind-konf/
├── src/
│   ├── tailwindConf/
│   │   ├── colorPalette/
│   │   │   └── palette-controller.json
│   ├── components/
│   └── main.js
└── tailwind.config.js

palette-controller.json:

[
  {
    "paletteName": "primary",
    "swatches": [
      {"name": "primary-white", "color": "#f1f4f4"},
      // Other colors...
      {"name": "primary-900", "color": "#052e2e"}
    ]
  },
  {
    "paletteName": "secondary",
    "swatches": [
      {"name": "secondary-white", "color": "#f4f1f1"},
      // Other colors...
      {"name": "secondary-900", "color": "#2e0505"}
    ]
  },
  {
    "paletteName": "gray",
    "swatches": [
      {"name": "gray-white", "color": "#f1f4f4"},
      // Other colors...
      {"name": "gray-900", "color": "#171c1c"}
    ]
  }
]

tailwind.config.js:

const colors = require('./src/tailwindConf/colorPalette/palette-controller.json');

module.exports = {
  content: [
    './public/**/*.html',
    './src/**/*.{vue,js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {
      colors: {
        ...colors.reduce((acc, palette) => {
          acc[palette.paletteName] = palette.swatches.reduce((swatchAcc, swatch) => {
            swatchAcc[swatch.name] = swatch.color;
            return swatchAcc;
          }, {});
          return acc;
        }, {})
      },
    },
  },

};

Details: My configuration includes a palette-controller.json file where I have defined color shades for 'primary', 'secondary', and 'gray'. These colors are dynamically imported into my tailwind.config.js and are supposed to extend the default Tailwind theme. However, in my compiled CSS, there are no classes like bg-primary-500, text-secondary-300, or even the custom 'gray' classes I defined. Instead, only the default 'gray' classes from Tailwind are available. The JSON file is correctly loaded and parsed without errors in the build process. Additional Context:

All paths and import statements in the configuration have been verified for accuracy. This issue is specifically problematic because it prevents me from using my brand colors defined under 'primary' and 'secondary', and the custom 'gray' palette is completely ignored.

Question: Why aren't the 'primary', 'secondary', and custom 'gray' color classes being generated by Tailwind CSS, and how can I ensure that Tailwind uses the color specifications from my JSON file instead of its default palette?

Upvotes: 0

Views: 129

Answers (1)

Wongjn
Wongjn

Reputation: 24408

As per this inline snippet:

const colors = [
  {
    paletteName: "primary",
    swatches: [
      {
        name: "primary-white",
        color: "#f1f4f4",
      },
      // Other colors...
      {
        name: "primary-900",
        color: "#052e2e",
      },
    ],
  },
  {
    paletteName: "secondary",
    swatches: [
      {
        name: "secondary-white",
        color: "#f4f1f1",
      },
      // Other colors...
      {
        name: "secondary-900",
        color: "#2e0505",
      },
    ],
  },
  {
    paletteName: "gray",
    swatches: [
      {
        name: "gray-white",
        color: "#f1f4f4",
      },
      // Other colors...
      {
        name: "gray-900",
        color: "#171c1c",
      },
    ],
  },
];

console.log({
  ...colors.reduce((acc, palette) => {
    acc[palette.paletteName] = palette.swatches.reduce((swatchAcc, swatch) => {
      swatchAcc[swatch.name] = swatch.color;
      return swatchAcc;
    }, {});
    return acc;
  }, {}),
});

The colors object you produce resolves to:

{
  "primary": {
    "primary-white": "#f1f4f4",
    "primary-900": "#052e2e"
  },
  "secondary": {
    "secondary-white": "#f4f1f1",
    "secondary-900": "#2e0505"
  },
  "gray": {
    "gray-white": "#f1f4f4",
    "gray-900": "#171c1c"
  }
}

The parent key(s) of each value is also part of the color value key when used in classes. Thus your color values would be resolved to classes like bg-primary-primary-500, text-secondary-secondary-300, text-gray-gray-900, etc., not bg-primary-500, text-secondary-300, text-gray-900, etc.

If you want classes like bg-primary-500, text-secondary-300, text-gray-900, etc. to reference your colors, consider reworking your JSON transpilation in the Tailwind configuration to remove the <indent>- prefix from the name of the swatches, like:

const colors = [
  {
    paletteName: "primary",
    swatches: [
      {
        name: "primary-white",
        color: "#f1f4f4",
      },
      // Other colors...
      {
        name: "primary-900",
        color: "#052e2e",
      },
    ],
  },
  {
    paletteName: "secondary",
    swatches: [
      {
        name: "secondary-white",
        color: "#f4f1f1",
      },
      // Other colors...
      {
        name: "secondary-900",
        color: "#2e0505",
      },
    ],
  },
  {
    paletteName: "gray",
    swatches: [
      {
        name: "gray-white",
        color: "#f1f4f4",
      },
      // Other colors...
      {
        name: "gray-900",
        color: "#171c1c",
      },
    ],
  },
];

console.log({
  ...colors.reduce((acc, palette) => {
    // Use the name of the palette to get the start index to when we start to
    // trim, plus 1 for the dash (`-`).
    const indexStart = palette.paletteName.length + 1;

    acc[palette.paletteName] = palette.swatches.reduce((swatchAcc, swatch) => {
      // Extract a substring from swatch.name that excludes the palette name
      // prefix.
      swatchAcc[swatch.name.substring(indexStart)] = swatch.color;
      return swatchAcc;
    }, {});
    return acc;
  }, {}),
});

This would then give you a resolved colors object of:

{
  "primary": {
    "900": "#052e2e",
    "white": "#f1f4f4"
  },
  "secondary": {
    "900": "#2e0505",
    "white": "#f4f1f1"
  },
  "gray": {
    "900": "#171c1c",
    "white": "#f1f4f4"
  }
}

And thus bg-primary-500, text-secondary-300, text-gray-900 would now be valid class candidates corresponding to your custom colors.

Upvotes: 0

Related Questions