Skip to content

Commit db6e064

Browse files
committed
suggest --spacing scale when used
- When `--value(--spacing)` is used, then `--spacing` theme key suggestions will be used. - When `--spacing(--value(integer))` is used, then `--spacing` scale suggestions will be used, but _only_ for `integer` values. - When `--spacing(--value(number))` is used, then `--spacing` scale suggestions will be used, but for all values.
1 parent 0cb043f commit db6e064

File tree

1 file changed

+77
-30
lines changed

1 file changed

+77
-30
lines changed

packages/tailwindcss/src/utilities.ts

+77-30
Original file line numberDiff line numberDiff line change
@@ -4731,11 +4731,20 @@ export function createCssUtility(node: AtRule) {
47314731
// If you then use `foo-1/2`, this is invalid, because the modifier is not used.
47324732

47334733
return (designSystem: DesignSystem) => {
4734-
let valueThemeKeys = new Set<`--${string}`>()
4735-
let valueLiterals = new Set<string>()
4736-
4737-
let modifierThemeKeys = new Set<`--${string}`>()
4738-
let modifierLiterals = new Set<string>()
4734+
let storage = {
4735+
'--value': {
4736+
usedSpacingInteger: false,
4737+
usedSpacingNumber: false,
4738+
themeKeys: new Set<`--${string}`>(),
4739+
literals: new Set<string>(),
4740+
},
4741+
'--modifier': {
4742+
usedSpacingInteger: false,
4743+
usedSpacingNumber: false,
4744+
themeKeys: new Set<`--${string}`>(),
4745+
literals: new Set<string>(),
4746+
},
4747+
}
47394748

47404749
// Pre-process the AST to make it easier to work with.
47414750
//
@@ -4762,6 +4771,41 @@ export function createCssUtility(node: AtRule) {
47624771
// `\\*` or not inserting whitespace) then most of these can go away.
47634772
ValueParser.walk(declarationValueAst, (fn) => {
47644773
if (fn.kind !== 'function') return
4774+
4775+
// Track usage of `--spacing(…)`
4776+
if (
4777+
fn.value === '--spacing' &&
4778+
// Quick bail check if we already know that `--value` and `--modifier` are
4779+
// using the full `--spacing` theme scale.
4780+
!(storage['--modifier'].usedSpacingNumber && storage['--value'].usedSpacingNumber)
4781+
) {
4782+
ValueParser.walk(fn.nodes, (node) => {
4783+
if (node.kind !== 'function') return
4784+
if (node.value !== '--value' && node.value !== '--modifier') return
4785+
const key = node.value
4786+
4787+
for (let arg of node.nodes) {
4788+
if (arg.kind !== 'word') continue
4789+
4790+
if (arg.value === 'integer') {
4791+
storage[key].usedSpacingInteger ||= true
4792+
} else if (arg.value === 'number') {
4793+
storage[key].usedSpacingNumber ||= true
4794+
4795+
// Once both `--value` and `--modifier` are using the full
4796+
// `number` spacing scale, then there's no need to continue
4797+
if (
4798+
storage['--modifier'].usedSpacingNumber &&
4799+
storage['--value'].usedSpacingNumber
4800+
) {
4801+
return ValueParser.ValueWalkAction.Stop
4802+
}
4803+
}
4804+
}
4805+
})
4806+
return ValueParser.ValueWalkAction.Continue
4807+
}
4808+
47654809
if (fn.value !== '--value' && fn.value !== '--modifier') return
47664810

47674811
let args = segment(ValueParser.toCss(fn.nodes), ',')
@@ -4796,23 +4840,13 @@ export function createCssUtility(node: AtRule) {
47964840
node.value[0] === node.value[node.value.length - 1]
47974841
) {
47984842
let value = node.value.slice(1, -1)
4799-
4800-
if (fn.value === '--value') {
4801-
valueLiterals.add(value)
4802-
} else if (fn.value === '--modifier') {
4803-
modifierLiterals.add(value)
4804-
}
4843+
storage[fn.value].literals.add(value)
48054844
}
48064845

48074846
// Track theme keys
48084847
else if (node.kind === 'word' && node.value[0] === '-' && node.value[1] === '-') {
48094848
let value = node.value.replace(/-\*.*$/g, '') as `--${string}`
4810-
4811-
if (fn.value === '--value') {
4812-
valueThemeKeys.add(value)
4813-
} else if (fn.value === '--modifier') {
4814-
modifierThemeKeys.add(value)
4815-
}
4849+
storage[fn.value].themeKeys.add(value)
48164850
}
48174851
}
48184852
})
@@ -4949,20 +4983,33 @@ export function createCssUtility(node: AtRule) {
49494983
})
49504984

49514985
designSystem.utilities.suggest(name.slice(0, -2), () => {
4952-
let values = []
4953-
for (let value of valueLiterals) {
4954-
values.push(value)
4955-
}
4956-
for (let value of designSystem.theme.keysInNamespaces(valueThemeKeys)) {
4957-
values.push(value)
4958-
}
4986+
let values: string[] = []
4987+
let modifiers: string[] = []
4988+
4989+
for (let [target, { literals, usedSpacingNumber, usedSpacingInteger, themeKeys }] of [
4990+
[values, storage['--value']],
4991+
[modifiers, storage['--modifier']],
4992+
] as const) {
4993+
// Suggest literal values. E.g.: `--value('literal')`
4994+
for (let value of literals) {
4995+
target.push(value)
4996+
}
49594997

4960-
let modifiers = []
4961-
for (let modifier of modifierLiterals) {
4962-
modifiers.push(modifier)
4963-
}
4964-
for (let value of designSystem.theme.keysInNamespaces(modifierThemeKeys)) {
4965-
modifiers.push(value)
4998+
// Suggest `--spacing(…)` values. E.g.: `--spacing(--value(integer))`
4999+
if (usedSpacingNumber) {
5000+
target.push(...DEFAULT_SPACING_SUGGESTIONS)
5001+
} else if (usedSpacingInteger) {
5002+
for (let value of DEFAULT_SPACING_SUGGESTIONS) {
5003+
if (isPositiveInteger(value)) {
5004+
target.push(value)
5005+
}
5006+
}
5007+
}
5008+
5009+
// Suggest theme values. E.g.: `--value(--color-*)`
5010+
for (let value of designSystem.theme.keysInNamespaces(themeKeys)) {
5011+
target.push(value)
5012+
}
49665013
}
49675014

49685015
return [{ values, modifiers }] satisfies SuggestionGroup[]

0 commit comments

Comments
 (0)