mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Support URL in arbitrary values (#5587)
* add url to resolveArbitraryValue list
* add `asURL` data type
* add `bg-[url('..')]` regex
* allow for `resolveArbitraryValue` to be an array
* prevent spaces around `-` when in a `url`
* add tests to verify `bg-[url('...')]` and `stroke-[url(...)]`
This commit is contained in:
parent
a4d1bdb7fa
commit
abcd9acd18
@ -17,6 +17,7 @@ import {
|
||||
transformAllClasses,
|
||||
transformLastClasses,
|
||||
asLength,
|
||||
asURL,
|
||||
asLookupValue,
|
||||
} from './util/pluginUtils'
|
||||
import packageJson from '../package.json'
|
||||
@ -1361,7 +1362,7 @@ export let backgroundOpacity = createUtilityPlugin('backgroundOpacity', [
|
||||
export let backgroundImage = createUtilityPlugin(
|
||||
'backgroundImage',
|
||||
[['bg', ['background-image']]],
|
||||
{ resolveArbitraryValue: asLookupValue }
|
||||
{ resolveArbitraryValue: [asLookupValue, asURL] }
|
||||
)
|
||||
export let gradientColorStops = (() => {
|
||||
function transparentTo(value) {
|
||||
@ -1482,7 +1483,7 @@ export let stroke = ({ matchUtilities, theme }) => {
|
||||
}
|
||||
|
||||
export let strokeWidth = createUtilityPlugin('strokeWidth', [['stroke', ['stroke-width']]], {
|
||||
resolveArbitraryValue: asLength,
|
||||
resolveArbitraryValue: [asLength, asURL],
|
||||
})
|
||||
|
||||
export let objectFit = ({ addUtilities }) => {
|
||||
|
||||
@ -7,6 +7,8 @@ let env = sharedState.env
|
||||
let contentMatchCache = sharedState.contentMatchCache
|
||||
|
||||
const PATTERNS = [
|
||||
/([^<>"'`\s]*\[\w*\('[^"'`\s]*'\)\])/.source, // bg-[url('...')]
|
||||
/([^<>"'`\s]*\[\w*\("[^"'`\s]*"\)\])/.source, // bg-[url("...")]
|
||||
/([^<>"'`\s]*\['[^"'`\s]*'\])/.source, // `content-['hello']` but not `content-['hello']']`
|
||||
/([^<>"'`\s]*\["[^"'`\s]*"\])/.source, // `content-["hello"]` but not `content-["hello"]"]`
|
||||
/([^<>"'`\s]*\[[^"'`\s]+\])/.source, // `fill-[#bada55]`
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
import transformThemeValue from './transformThemeValue'
|
||||
import { asValue, asColor, asAngle, asLength, asLookupValue } from '../util/pluginUtils'
|
||||
import { asValue, asColor, asAngle, asLength, asURL, asLookupValue } from '../util/pluginUtils'
|
||||
|
||||
let asMap = new Map([
|
||||
[asValue, 'any'],
|
||||
[asColor, 'color'],
|
||||
[asAngle, 'angle'],
|
||||
[asLength, 'length'],
|
||||
[asURL, 'url'],
|
||||
[asLookupValue, 'lookup'],
|
||||
])
|
||||
|
||||
@ -38,7 +39,9 @@ export default function createUtilityPlugin(
|
||||
Object.entries(theme(themeKey) ?? {}).filter(([modifier]) => modifier !== 'DEFAULT')
|
||||
)
|
||||
: theme(themeKey),
|
||||
type: asMap.get(resolveArbitraryValue) ?? 'any',
|
||||
type: Array.isArray(resolveArbitraryValue)
|
||||
? resolveArbitraryValue.map((typeResolver) => asMap.get(typeResolver) ?? 'any')
|
||||
: asMap.get(resolveArbitraryValue) ?? 'any',
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@ -175,6 +175,9 @@ export function asValue(modifier, lookup = {}, { validate = () => true } = {}) {
|
||||
.replace(/^_/g, ' ')
|
||||
.replace(/\\_/g, '_')
|
||||
|
||||
// Keep raw strings if it starts with `url(`
|
||||
if (value.startsWith('url(')) return value
|
||||
|
||||
// add spaces around operators inside calc() that do not follow an operator or (
|
||||
return value.replace(
|
||||
/(-?\d*\.?\d(?!\b-.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g,
|
||||
@ -236,6 +239,12 @@ export function asAngle(modifier, lookup = {}) {
|
||||
return asUnit(modifier, ['deg', 'grad', 'rad', 'turn'], lookup)
|
||||
}
|
||||
|
||||
export function asURL(modifier, lookup = {}) {
|
||||
return asValue(modifier, lookup, {
|
||||
validate: (value) => value.startsWith('url('),
|
||||
})
|
||||
}
|
||||
|
||||
export function asLength(modifier, lookup = {}) {
|
||||
return asUnit(
|
||||
modifier,
|
||||
@ -271,6 +280,7 @@ let typeMap = {
|
||||
color: asColor,
|
||||
angle: asAngle,
|
||||
length: asLength,
|
||||
url: asURL,
|
||||
lookup: asLookupValue,
|
||||
}
|
||||
|
||||
|
||||
@ -275,6 +275,12 @@
|
||||
.bg-opacity-\[var\(--value\)\] {
|
||||
--tw-bg-opacity: var(--value);
|
||||
}
|
||||
.bg-\[url\(\'\/path-to-image\.png\'\)\] {
|
||||
background-image: url('/path-to-image.png');
|
||||
}
|
||||
.bg-\[url\:var\(--url\)\] {
|
||||
background-image: var(--url);
|
||||
}
|
||||
.from-\[\#da5b66\] {
|
||||
--tw-gradient-from: #da5b66;
|
||||
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgb(218 91 102 / 0));
|
||||
@ -305,6 +311,9 @@
|
||||
.stroke-\[\#da5b66\] {
|
||||
stroke: #da5b66;
|
||||
}
|
||||
.stroke-\[url\(\#icon-gradient\)\] {
|
||||
stroke-width: url(#icon-gradient);
|
||||
}
|
||||
.object-\[50\%\2c 50\%\] {
|
||||
object-position: 50% 50%;
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
<div class="bg-[#0f0] bg-[#ff0000] bg-[#0000ffcc]"></div>
|
||||
<div class="bg-[rgb(123,123,123)] bg-[rgba(123,123,123,0.5)]"></div>
|
||||
<div class="bg-[hsl(0,100%,50%)] bg-[hsla(0,100%,50%,0.3)]"></div>
|
||||
<div class="bg-[url('/path-to-image.png')] bg-[url:var(--url)]"></div>
|
||||
<div class="bg-opacity-[0.11]"></div>
|
||||
<div class="bg-opacity-[var(--value)]"></div>
|
||||
<div class="border-[#f00]"></div>
|
||||
@ -116,6 +117,7 @@
|
||||
<div class="object-[top,right]"></div>
|
||||
<div class="object-[var(--position)]"></div>
|
||||
<div class="stroke-[#da5b66]"></div>
|
||||
<div class="stroke-[url(#icon-gradient)]"></div>
|
||||
<div class="leading-[var(--leading)]"></div>
|
||||
<div class="tracking-[var(--tracking)]"></div>
|
||||
<div class="placeholder-[var(--placeholder)]"></div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user