Skip to content

Commit

Permalink
Handle color transformations properly with theme(...) for all relev…
Browse files Browse the repository at this point in the history
…ant plugins (#5871)

* call function for colors that are not in colors

* add all color related thingies

* transformThemeValue in a very verbose way

* handle functions by default

* cleanup, make sure we handle functions everywhere

* update changelog

Co-authored-by: Bill Criswell <bill_criswell@comcast.com>
  • Loading branch information
RobinMalfait and Bill Criswell authored Oct 25, 2021
1 parent 1218b3e commit 5058275
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Cleanup duplicate properties ([#5830](https://github.com/tailwindlabs/tailwindcss/pull/5830))
- Allow `_` inside `url()` when using arbitrary values ([#5853](https://github.com/tailwindlabs/tailwindcss/pull/5853))
- Prevent crashes when using comments in `@layer` AtRules ([#5854](https://github.com/tailwindlabs/tailwindcss/pull/5854))
- Handle color transformations properly with `theme(...)` for all relevant plugins ([#4533](https://github.com/tailwindlabs/tailwindcss/pull/4533), [#5871](https://github.com/tailwindlabs/tailwindcss/pull/5871))

## [3.0.0-alpha.1] - 2021-10-01

Expand Down
29 changes: 22 additions & 7 deletions src/util/transformThemeValue.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import postcss from 'postcss'

export default function transformThemeValue(themeSection) {
if (['fontSize', 'outline'].includes(themeSection)) {
return (value) => (Array.isArray(value) ? value[0] : value)
return (value) => {
if (typeof value === 'function') value = value({})
if (Array.isArray(value)) value = value[0]

return value
}
}

if (
Expand All @@ -20,18 +25,28 @@ export default function transformThemeValue(themeSection) {
'animation',
].includes(themeSection)
) {
return (value) => (Array.isArray(value) ? value.join(', ') : value)
return (value) => {
if (typeof value === 'function') value = value({})
if (Array.isArray(value)) value = value.join(', ')

return value
}
}

// For backwards compatibility reasons, before we switched to underscores
// instead of commas for arbitrary values.
if (['gridTemplateColumns', 'gridTemplateRows', 'objectPosition'].includes(themeSection)) {
return (value) => (typeof value === 'string' ? postcss.list.comma(value).join(' ') : value)
}
return (value) => {
if (typeof value === 'function') value = value({})
if (typeof value === 'string') value = postcss.list.comma(value).join(' ')

if (themeSection === 'colors') {
return (value) => (typeof value === 'function' ? value({}) : value)
return value
}
}

return (value) => value
return (value) => {
if (typeof value === 'function') value = value({})

return value
}
}
54 changes: 54 additions & 0 deletions tests/evaluateTailwindFunctions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,60 @@ test('it looks up values in the theme using dot notation', () => {
})
})

test('color can be a function', () => {
const input = `
.backgroundColor { color: theme('backgroundColor.fn') }
.borderColor { color: theme('borderColor.fn') }
.caretColor { color: theme('caretColor.fn') }
.colors { color: theme('colors.fn') }
.divideColor { color: theme('divideColor.fn') }
.fill { color: theme('fill.fn') }
.gradientColorStops { color: theme('gradientColorStops.fn') }
.placeholderColor { color: theme('placeholderColor.fn') }
.ringColor { color: theme('ringColor.fn') }
.ringOffsetColor { color: theme('ringOffsetColor.fn') }
.stroke { color: theme('stroke.fn') }
.textColor { color: theme('textColor.fn') }
`

const output = `
.backgroundColor { color: #f00 }
.borderColor { color: #f00 }
.caretColor { color: #f00 }
.colors { color: #f00 }
.divideColor { color: #f00 }
.fill { color: #f00 }
.gradientColorStops { color: #f00 }
.placeholderColor { color: #f00 }
.ringColor { color: #f00 }
.ringOffsetColor { color: #f00 }
.stroke { color: #f00 }
.textColor { color: #f00 }
`

const fn = () => `#f00`

return run(input, {
theme: {
backgroundColor: { fn },
borderColor: { fn },
caretColor: { fn },
colors: { fn },
divideColor: { fn },
fill: { fn },
gradientColorStops: { fn },
placeholderColor: { fn },
ringColor: { fn },
ringOffsetColor: { fn },
stroke: { fn },
textColor: { fn },
},
}).then((result) => {
expect(result.css).toEqual(output)
expect(result.warnings().length).toBe(0)
})
})

test('quotes are optional around the lookup path', () => {
const input = `
.banana { color: theme(colors.yellow); }
Expand Down

0 comments on commit 5058275

Please sign in to comment.