From 99f2127b7dafdbe9e98d6dd9643c44a8d9b52363 Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Mon, 14 Oct 2024 12:29:12 +0200 Subject: [PATCH] Callback in theme properties is also the theme function (#14659) Something we noticed while testing the codemods on one of our codebases is that the callback passed to the `theme` function properties doesn't only expose some properties like `colors`, but it's also a function itself. ```ts /** @type {import('tailwindcss').Config} */ export default { theme: { extend: { colors: (theme) => { // The `theme` is a theme function _and_ the object... console.log(theme('spacing.2'), theme.colors.red['500']) return {} }, }, }, plugins: [], } ``` E.g.: https://play.tailwindcss.com/eV7Jgv17X1?file=config --- h/t to @RobinMalfait for the issue description --- CHANGELOG.md | 1 + .../src/compat/config/resolve-config.test.ts | 8 ++++++++ .../src/compat/config/resolve-config.ts | 14 ++++++++------ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5af6d0fdd..b049c4cf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add support for `tailwindcss/colors.js`, `tailwindcss/defaultTheme.js`, and `tailwindcss/plugin.js` exports ([#14595](https://github.com/tailwindlabs/tailwindcss/pull/14595)) - Support `keyframes` in JS config file themes ([#14594](https://github.com/tailwindlabs/tailwindcss/pull/14594)) - Support the `color` parameter in JS theme configuration callbacks ([#14651](https://github.com/tailwindlabs/tailwindcss/pull/14651)) +- Support using the object parameter in the JS theme configuration callback as `theme()` function ([#14659](https://github.com/tailwindlabs/tailwindcss/pull/14659)) - _Upgrade (experimental)_: Migrate v3 PostCSS setups to v4 in some cases ([#14612](https://github.com/tailwindlabs/tailwindcss/pull/14612)) - _Upgrade (experimental)_: Automatically discover JavaScript config files ([#14597](https://github.com/tailwindlabs/tailwindcss/pull/14597)) - _Upgrade (experimental)_: Migrate legacy classes to the v4 alternative ([#14643](https://github.com/tailwindlabs/tailwindcss/pull/14643)) diff --git a/packages/tailwindcss/src/compat/config/resolve-config.test.ts b/packages/tailwindcss/src/compat/config/resolve-config.test.ts index d755cf8e1..ebe455059 100644 --- a/packages/tailwindcss/src/compat/config/resolve-config.test.ts +++ b/packages/tailwindcss/src/compat/config/resolve-config.test.ts @@ -202,6 +202,10 @@ test('theme keys can read from the CSS theme', () => { // Gives access to the colors object directly primary: colors.green, }), + transitionColor: (theme) => ({ + // The parameter object is also the theme function + ...theme('colors'), + }), }, }, base: '/root', @@ -237,6 +241,10 @@ test('theme keys can read from the CSS theme', () => { '950': '#052e16', }, }, + transitionColor: { + red: 'red', + green: 'green', + }, }, }) }) diff --git a/packages/tailwindcss/src/compat/config/resolve-config.ts b/packages/tailwindcss/src/compat/config/resolve-config.ts index fbbf807ab..b0d78de2e 100644 --- a/packages/tailwindcss/src/compat/config/resolve-config.ts +++ b/packages/tailwindcss/src/compat/config/resolve-config.ts @@ -116,8 +116,9 @@ export function mergeThemeExtension( return undefined } -export interface PluginUtils { - theme(keypath: string, defaultValue?: any): any +type ThemeFunction = (keypath: string, defaultValue?: any) => any +export type PluginUtils = ThemeFunction & { + theme: ThemeFunction colors: typeof colors } @@ -176,14 +177,15 @@ function extractConfigs(ctx: ResolutionContext, { config, base, path }: ConfigFi } function mergeTheme(ctx: ResolutionContext) { - let api: PluginUtils = { - theme: createThemeFn(ctx.design, () => ctx.theme, resolveValue), + let themeFn = createThemeFn(ctx.design, () => ctx.theme, resolveValue) + let theme = Object.assign(themeFn, { + theme: themeFn, colors, - } + }) function resolveValue(value: ThemeValue | null | undefined): ResolvedThemeValue { if (typeof value === 'function') { - return value(api) ?? null + return value(theme) ?? null } return value ?? null