Skip to content

Commit 2ac1859

Browse files
committed
🧹 chore: simplify looking up values in the theme (which unfortunately means that keys with . in them are no longer supported -- but they may have never been to begin with seeing as this is a tailwind limitation?)
1 parent 5fcc433 commit 2ac1859

File tree

3 files changed

+183
-97
lines changed

3 files changed

+183
-97
lines changed

projects/tailwindcss-theme-variants/src/index.ts

+22-51
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,47 @@
33
// eslint-disable-next-line import/no-unresolved
44
import plugin from "tailwindcss/plugin";
55

6+
import type { PluginTools, TailwindCSSConfig } from "@navith/tailwindcss-plugin-author-types";
67
import type {
7-
PluginTools, TailwindCSSConfig, ThemeValue,
8-
} from "@navith/tailwindcss-plugin-author-types";
9-
import type {
10-
ObjectOfNestedStrings, ThisPluginOptions, ThisPluginTheme,
8+
ObjectOfNestedStrings, SemanticUtility, ThisPluginOptions, ThisPluginTheme,
119
} from "./types";
1210
import { addParent } from "./selectors";
1311

14-
const DEFAULT = ["DEFAULT"];
12+
const DEFAULT = "DEFAULT";
1513

1614
type FlattenedSemantics = Record<string, Record<string, Map<string, string>>>;
1715
const flattenSemantics = (allThemes: [string, ThisPluginTheme][]): FlattenedSemantics => {
1816
const semanticsAccumulating = {} as FlattenedSemantics;
1917

2018
for (const [themeName, themeConfiguration] of allThemes) {
21-
for (const [utility, utilityValues] of Object.entries(themeConfiguration.semantics ?? {})) {
22-
if (!semanticsAccumulating[utility]) {
23-
semanticsAccumulating[utility] = {};
19+
for (const [utilityName, utilityValues] of Object.entries(themeConfiguration.semantics ?? {})) {
20+
if (!semanticsAccumulating[utilityName]) {
21+
semanticsAccumulating[utilityName] = {};
2422
}
2523

2624
for (const [rootName, rootValue] of Object.entries(utilityValues ?? {})) {
27-
const thing = semanticsAccumulating[utility];
28-
const flatten = ([name, value]: [string, string | ObjectOfNestedStrings]) => {
25+
const thing = semanticsAccumulating[utilityName];
26+
const flatten = (name: string, value: string | ObjectOfNestedStrings) => {
2927
if (typeof value === "string") {
30-
const computedName = DEFAULT.includes(name) ? rootName : `${rootName}-${name}`;
28+
const computedName = name === DEFAULT ? rootName : `${rootName}-${name}`;
3129
if (!thing[computedName]) {
3230
// Use Maps to guarantee order matches theme order
3331
thing[computedName] = new Map();
3432
}
3533
thing[computedName].set(themeName, value);
3634
} else {
3735
for (const [nestedName, nestedValue] of Object.entries(value)) {
38-
const computedName = DEFAULT.includes(nestedName) ? name : `${name}-${nestedName}`;
39-
flatten([computedName, nestedValue]);
36+
const computedName = nestedName === DEFAULT ? name : `${name}-${nestedName}`;
37+
flatten(computedName, nestedValue);
4038
}
4139
}
4240
};
4341

4442
if (typeof rootValue === "string") {
45-
flatten([DEFAULT[0], rootValue]);
43+
flatten(DEFAULT, rootValue);
4644
} else {
4745
for (const [name, value] of Object.entries(rootValue)) {
48-
flatten([name, value]);
46+
flatten(name, value);
4947
}
5048
}
5149
}
@@ -60,16 +58,13 @@ const thisPlugin = plugin.withOptions(({
6058
addBase, addVariant, e, postcss, theme: lookupTheme,
6159
}: PluginTools): void => {
6260
const allThemes = Object.entries(themes ?? {});
63-
if (allThemes.length === 0) {
64-
console.warn("tailwindcss-theme-variants: no themes were given in this plugin's configuration under the `themes` key, so no variants can be generated. this can be fixed by specifying a theme like `light: { selector: '.light' }` in `themes` of this plugin's configuration. see the README for more information");
65-
}
61+
if (allThemes.length === 0) console.warn("tailwindcss-theme-variants: no themes were given in this plugin's configuration under the `themes` key, so no variants can be generated. this can be fixed by specifying a theme like `light: { selector: '.light' }` in `themes` of this plugin's configuration. see the README for more information");
6662

6763
const firstTheme = allThemes[0][0];
6864

69-
const usesAnySelectors = allThemes.some(([_name, { selector }]) => selector);
70-
7165
// Implicitly disable `baseSelector` on behalf of the person only using media queries to set their themes
7266
// Otherwise use :root as the default `baseSelector`
67+
const usesAnySelectors = allThemes.some(([_name, { selector }]) => selector);
7368
const baseSelector = passedBaseSelector ?? (usesAnySelectors ? ":root" : "");
7469

7570
if (fallback) {
@@ -87,7 +82,6 @@ const thisPlugin = plugin.withOptions(({
8782
}
8883

8984
// Begin variants logic
90-
9185
for (const [themeName, { mediaQuery, selector }] of allThemes) {
9286
addVariant(themeName, ({ container, separator }) => {
9387
const originalContainer = container.clone();
@@ -106,7 +100,6 @@ const thisPlugin = plugin.withOptions(({
106100

107101
container.append(containerFallBack);
108102
} else {
109-
// TODO: debugging
110103
if (mediaQuery) {
111104
const queryAtRule = postcss.parse(mediaQuery).first;
112105

@@ -141,8 +134,6 @@ const thisPlugin = plugin.withOptions(({
141134
rule.selector = addParent(namedSelector, activator);
142135
});
143136

144-
if (mediaQuery) console.log("DEBUG: HI MEDIA QUERY AND SELECTOR!");
145-
146137
container.append(normalContainer);
147138
}
148139
}
@@ -172,30 +163,12 @@ const thisPlugin = plugin.withOptions(({
172163
throw new TypeError(`tailwindcss-theme-variants: the semantic variable "${variable}" was expected to have an initial ("constant") value for the "${themeName}" theme, but it is undefined. this can be fixed by specifying a value for "${variable}" in any utility's configuration in the "semantics" object under the "${themeName}" theme's configuration`);
173164
}
174165

175-
let lookupName = referenceValue;
176-
let realValue: ThemeValue;
166+
const { themeValueToVariableValue = (x) => x.toString() } = behavior[utilityName] ?? ({} as SemanticUtility);
177167

178-
const allHyphensAndPeriods: number[] = [];
179-
for (let i = 0; i < lookupName.length; i += 1) {
180-
if (lookupName[i] === "." || lookupName[i] === "-") allHyphensAndPeriods.push(i);
181-
}
182-
183-
const { themeValueToVariableValue = (x: any): string => x } = behavior[utilityName] ?? {};
168+
const realValue = lookupTheme(`${utilityName}.${referenceValue}`, undefined);
169+
if (!realValue) throw new TypeError(`tailwindcss-theme-variants: the initial / constant value for the semantic variable named "${variable}" for the "${themeName}" theme couldn't be found; it should be named "${referenceValue}" ${referenceValue.includes(".") || referenceValue.includes("-") ? "(maybe with . in place of -?) " : ""}in \`theme.${utilityName}\`. this can be fixed by making sure the value you referenced (${referenceValue}) is in your Tailwind CSS \`theme\` configuration under \`${utilityName}\`.\nthere could be a mistake here; please create an issue if it actually does exist: https://github.com/JakeNavith/tailwindcss-theme-variants/issues`);
184170

185-
const toTry = 2 ** allHyphensAndPeriods.length;
186-
for (const bitmap of Array(toTry).keys()) {
187-
for (const [bit, index] of allHyphensAndPeriods.entries()) {
188-
lookupName = lookupName.substring(0, index) + (bitmap & (1 << bit) ? "." : "-") + lookupName.substring(index + 1);
189-
}
190-
const foundValue = lookupTheme(`${utilityName}.${lookupName}`, undefined);
191-
if (foundValue) realValue = foundValue;
192-
}
193-
194-
if (realValue) {
195-
semanticVariables[`--${variable}`] = themeValueToVariableValue(realValue);
196-
} else {
197-
throw new TypeError(`tailwindcss-theme-variants: the initial / constant value for the semantic variable named "${variable}" for the "${themeName}" theme couldn't be found; it should be named "${referenceValue}" ${referenceValue.includes(".") || referenceValue.includes("-") ? "(maybe with . in place of -?) " : ""}in \`theme.${utilityName}\`. this can be fixed by making sure the value you referenced (${referenceValue}) is in your Tailwind CSS \`theme\` configuration under \`${utilityName}\`.\nthere could be a mistake here; please create an issue if it actually does exist: https://github.com/JakeNavith/tailwindcss-theme-variants/issues`);
198-
}
171+
semanticVariables[`--${variable}`] = themeValueToVariableValue(realValue.toString());
199172
}
200173
}
201174

@@ -239,9 +212,7 @@ const thisPlugin = plugin.withOptions(({
239212
// End semantics logic
240213
},
241214

242-
({
243-
themes, utilities,
244-
}: ThisPluginOptions) => {
215+
({ themes, utilities }: ThisPluginOptions) => {
245216
const everySemantics = Object.values(themes).every((theme) => theme.semantics);
246217

247218
const extendedConfig: TailwindCSSConfig & { theme: { extend: NonNullable<TailwindCSSConfig["theme"]> } } = {
@@ -259,11 +230,11 @@ const thisPlugin = plugin.withOptions(({
259230
for (const [configKey, themeMaps] of Object.entries(semantics)) {
260231
extendedConfig.theme.extend[configKey] = {};
261232

262-
const { variableValueToThemeValue = (x: any): any => x } = behavior[configKey] ?? {};
233+
const { variableValueToThemeValue = (x) => x } = behavior[configKey] ?? ({} as SemanticUtility);
263234
for (const semanticName of Object.keys(themeMaps)) {
264235
const variableValueToThemeValued = variableValueToThemeValue(`var(--${semanticName})`);
265236
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
266-
// @ts-ignore it's typed wrong
237+
// @ts-expect-error it's typed wrong
267238
extendedConfig.theme.extend[configKey][semanticName] = variableValueToThemeValued;
268239
}
269240
}

projects/tailwindcss-theme-variants/src/types.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { WrappedPlugin } from "@navith/tailwindcss-plugin-author-types";
1+
import { ThemeValue, WrappedPlugin } from "@navith/tailwindcss-plugin-author-types";
22

33
export interface ThisPluginThemeSelectorAndMediaQuery {
44
selector: string;
@@ -12,9 +12,11 @@ type RequireAtLeastOne<T, Keys extends keyof T = keyof T> =
1212
[K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>
1313
}[Keys]
1414

15+
type ColorThemeValue = (obj: { opacityValue?: string, opacityVariable?: string }) => string;
16+
1517
export type SemanticUtility = {
16-
themeValueToVariableValue?: (value: any) => string;
17-
variableValueToThemeValue?: (value: string) => any;
18+
themeValueToVariableValue?: (value: string) => string;
19+
variableValueToThemeValue?: (value: string) => (ThemeValue | ColorThemeValue);
1820
}
1921

2022
export type ObjectOfNestedStrings = {

0 commit comments

Comments
 (0)