init
This commit is contained in:
109
tailwind-plugin/tw-bs-grid.js
Normal file
109
tailwind-plugin/tw-bs-grid.js
Normal file
@@ -0,0 +1,109 @@
|
||||
import plugin from "tailwindcss/plugin";
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
module.exports = plugin.withOptions(() => {
|
||||
return ({ addComponents }) => {
|
||||
const gridColumns = 12;
|
||||
const gridGutterWidth = "1.5rem";
|
||||
const gridGutters = {
|
||||
0: "0",
|
||||
1: "0.25rem",
|
||||
2: "0.5rem",
|
||||
3: "1rem",
|
||||
4: "1.5rem",
|
||||
5: "3rem",
|
||||
};
|
||||
const respectImportant = true;
|
||||
const columns = Array.from({ length: gridColumns }, (_, i) => i + 1);
|
||||
const rowColsSteps = columns.slice(0, Math.floor(gridColumns / 2));
|
||||
|
||||
// row
|
||||
addComponents(
|
||||
{
|
||||
".row": {
|
||||
"--bs-gutter-x": gridGutterWidth,
|
||||
"--bs-gutter-y": 0,
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
marginTop: "calc(var(--bs-gutter-y) * -1)",
|
||||
marginRight: "calc(var(--bs-gutter-x) / -2)",
|
||||
marginLeft: "calc(var(--bs-gutter-x) / -2)",
|
||||
"& > *": {
|
||||
boxSizing: "border-box",
|
||||
flexShrink: 0,
|
||||
width: "100%",
|
||||
maxWidth: "100%",
|
||||
paddingRight: "calc(var(--bs-gutter-x) / 2)",
|
||||
paddingLeft: "calc(var(--bs-gutter-x) / 2)",
|
||||
marginTop: "var(--bs-gutter-y)",
|
||||
},
|
||||
},
|
||||
},
|
||||
{ respectImportant },
|
||||
);
|
||||
|
||||
// columns
|
||||
addComponents(
|
||||
[
|
||||
{
|
||||
".col": { flex: "1 0 0%" },
|
||||
".row-cols-auto": { "& > *": { flex: "0 0 auto", width: "auto" } },
|
||||
},
|
||||
...rowColsSteps.map((num) => ({
|
||||
[`.row-cols-${num}`]: {
|
||||
"& > *": { flex: "0 0 auto", width: `${100 / num}%` },
|
||||
},
|
||||
})),
|
||||
{ ".col-auto": { flex: "0 0 auto", width: "auto" } },
|
||||
...columns.map((num) => ({
|
||||
[`.col-${num}`]: {
|
||||
flex: "0 0 auto",
|
||||
width: `${(100 / gridColumns) * num}%`,
|
||||
},
|
||||
})),
|
||||
],
|
||||
{ respectImportant },
|
||||
);
|
||||
|
||||
// offset
|
||||
addComponents(
|
||||
[0, ...columns.slice(0, -1)].map((num) => ({
|
||||
[`.offset-${num}`]: { marginLeft: `${(100 / gridColumns) * num}%` },
|
||||
})),
|
||||
{ respectImportant },
|
||||
);
|
||||
|
||||
// gutters
|
||||
if (Object.keys(gridGutters).length) {
|
||||
const gutterComponents = Object.entries(gridGutters).reduce(
|
||||
(acc, [key, value]) => {
|
||||
acc[`.g-${key}`] = {
|
||||
"--bs-gutter-x": value,
|
||||
"--bs-gutter-y": value,
|
||||
};
|
||||
acc[`.gx-${key}`] = { "--bs-gutter-x": value };
|
||||
acc[`.gy-${key}`] = { "--bs-gutter-y": value };
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
addComponents(gutterComponents, { respectImportant });
|
||||
}
|
||||
|
||||
// order
|
||||
addComponents(
|
||||
[
|
||||
{
|
||||
".order-first": { order: "-1" },
|
||||
".order-last": { order: gridColumns + 1 },
|
||||
},
|
||||
...[0, ...columns].map((num) => ({
|
||||
[`.order-${num}`]: { order: String(num) },
|
||||
})),
|
||||
],
|
||||
{ respectImportant },
|
||||
);
|
||||
};
|
||||
});
|
||||
})();
|
||||
143
tailwind-plugin/tw-theme.js
Normal file
143
tailwind-plugin/tw-theme.js
Normal file
@@ -0,0 +1,143 @@
|
||||
const plugin = require("tailwindcss/plugin");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const themePath = path.join(__dirname, "../data/theme.json");
|
||||
const themeRead = fs.readFileSync(themePath, "utf8");
|
||||
const themeConfig = JSON.parse(themeRead);
|
||||
|
||||
// Helper to extract a clean font name.
|
||||
const findFont = (fontStr) =>
|
||||
fontStr.replace(/\+/g, " ").replace(/:[^:]+/g, "");
|
||||
|
||||
// Set font families dynamically, filtering out 'type' keys
|
||||
const fontFamilies = Object.entries(themeConfig.fonts.font_family)
|
||||
.filter(([key]) => !key.includes("type"))
|
||||
.reduce((acc, [key, font]) => {
|
||||
acc[key] =
|
||||
`${findFont(font)}, ${themeConfig.fonts.font_family[`${key}_type`] || "sans-serif"}`;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const defaultColorGroups = [
|
||||
{ colors: themeConfig.colors.default.theme_color, prefix: "" },
|
||||
{ colors: themeConfig.colors.default.text_color, prefix: "" },
|
||||
];
|
||||
const darkColorGroups = [];
|
||||
if (themeConfig.colors.darkmode?.theme_color) {
|
||||
darkColorGroups.push({
|
||||
colors: themeConfig.colors.darkmode.theme_color,
|
||||
prefix: "darkmode-",
|
||||
});
|
||||
}
|
||||
if (themeConfig.colors.darkmode?.text_color) {
|
||||
darkColorGroups.push({
|
||||
colors: themeConfig.colors.darkmode.text_color,
|
||||
prefix: "darkmode-",
|
||||
});
|
||||
}
|
||||
|
||||
const getVars = (groups) => {
|
||||
const vars = {};
|
||||
groups.forEach(({ colors, prefix }) => {
|
||||
Object.entries(colors).forEach(([k, v]) => {
|
||||
const cssKey = k.replace(/_/g, "-");
|
||||
vars[`--color-${prefix}${cssKey}`] = v;
|
||||
});
|
||||
});
|
||||
return vars;
|
||||
};
|
||||
|
||||
const defaultVars = getVars(defaultColorGroups);
|
||||
const darkVars = getVars(darkColorGroups);
|
||||
|
||||
const baseSize = Number(themeConfig.fonts.font_size.base);
|
||||
const scale = Number(themeConfig.fonts.font_size.scale);
|
||||
const calculateFontSizes = (base, scale) => {
|
||||
const sizes = {};
|
||||
let currentSize = scale;
|
||||
for (let i = 6; i >= 1; i--) {
|
||||
sizes[`h${i}`] = `${currentSize}rem`;
|
||||
sizes[`h${i}-sm`] = `${currentSize * 0.9}rem`;
|
||||
currentSize *= scale;
|
||||
}
|
||||
sizes.base = `${base}px`;
|
||||
sizes["base-sm"] = `${base * 0.8}px`;
|
||||
return sizes;
|
||||
};
|
||||
const fontSizes = calculateFontSizes(baseSize, scale);
|
||||
|
||||
const fontVars = {};
|
||||
Object.entries(fontSizes).forEach(([key, value]) => {
|
||||
fontVars[`--text-${key}`] = value;
|
||||
});
|
||||
Object.entries(fontFamilies).forEach(([key, font]) => {
|
||||
fontVars[`--font-${key}`] = font;
|
||||
});
|
||||
|
||||
const baseVars = { ...fontVars, ...defaultVars };
|
||||
|
||||
// Build a colorsMap including both sets
|
||||
const colorsMap = {};
|
||||
[...defaultColorGroups, ...darkColorGroups].forEach(({ colors, prefix }) => {
|
||||
Object.entries(colors).forEach(([key]) => {
|
||||
const cssKey = key.replace(/_/g, "-");
|
||||
colorsMap[prefix + cssKey] = `var(--color-${prefix}${cssKey})`;
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = plugin.withOptions(() => {
|
||||
return function ({ addBase, addUtilities, matchUtilities }) {
|
||||
// Default vars on :root; dark vars on .dark
|
||||
addBase({
|
||||
":root": baseVars,
|
||||
".dark": darkVars,
|
||||
});
|
||||
|
||||
const fontUtils = {};
|
||||
Object.keys(fontFamilies).forEach((key) => {
|
||||
fontUtils[`.font-${key}`] = { fontFamily: `var(--font-${key})` };
|
||||
});
|
||||
Object.keys(fontSizes).forEach((key) => {
|
||||
fontUtils[`.text-${key}`] = { fontSize: `var(--text-${key})` };
|
||||
});
|
||||
addUtilities(fontUtils, {
|
||||
variants: ["responsive", "hover", "focus", "active", "disabled"],
|
||||
});
|
||||
|
||||
matchUtilities(
|
||||
{
|
||||
bg: (value) => ({ backgroundColor: value }),
|
||||
text: (value) => ({ color: value }),
|
||||
border: (value) => ({ borderColor: value }),
|
||||
fill: (value) => ({ fill: value }),
|
||||
stroke: (value) => ({ stroke: value }),
|
||||
},
|
||||
{ values: colorsMap, type: "color" },
|
||||
);
|
||||
|
||||
matchUtilities(
|
||||
{
|
||||
from: (value) => ({
|
||||
"--tw-gradient-from": value,
|
||||
"--tw-gradient-via-stops":
|
||||
"var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))",
|
||||
"--tw-gradient-stops":
|
||||
"var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))",
|
||||
}),
|
||||
to: (value) => ({
|
||||
"--tw-gradient-to": value,
|
||||
"--tw-gradient-via-stops":
|
||||
"var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))",
|
||||
"--tw-gradient-stops":
|
||||
"var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))",
|
||||
}),
|
||||
via: (value) => ({
|
||||
"--tw-gradient-via": value,
|
||||
"--tw-gradient-via-stops":
|
||||
"var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position)",
|
||||
}),
|
||||
},
|
||||
{ values: colorsMap, type: "color" },
|
||||
);
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user