mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Show suggestions for fractions in IntelliSense (#16353)
Fixes https://github.com/tailwindlabs/tailwindcss-intellisense/issues/1178 (partially) An IntelliSense PR (+ Play update) is required to make this work better with v4: https://github.com/tailwindlabs/tailwindcss-intellisense/pull/1182 <img width="671" alt="Screenshot 2025-02-07 at 15 19 59" src="https://github.com/user-attachments/assets/7642b80c-f431-4a1e-964d-2a98ffe7a67a" />
This commit is contained in:
parent
f995dae5ca
commit
aad440ecf6
@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Export `tailwindcss/lib/util/flattenColorPalette.js` for backward compatibility ([#16411](https://github.com/tailwindlabs/tailwindcss/pull/16411))
|
||||
- Fix sorting numeric utilities when they have different magnitudes ([#16414](https://github.com/tailwindlabs/tailwindcss/pull/16414))
|
||||
- Show suggestions for fractions in IntelliSense ([#16353](https://github.com/tailwindlabs/tailwindcss/pull/16353))
|
||||
|
||||
## [4.0.6] - 2025-02-10
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -2,19 +2,34 @@ import { styleRule, walkDepth } from './ast'
|
||||
import { applyVariant } from './compile'
|
||||
import type { DesignSystem } from './design-system'
|
||||
import { compare } from './utils/compare'
|
||||
import { DefaultMap } from './utils/default-map'
|
||||
|
||||
interface ClassMetadata {
|
||||
modifiers: string[]
|
||||
}
|
||||
|
||||
export type ClassItem = {
|
||||
name: string
|
||||
utility: string
|
||||
fraction: boolean
|
||||
modifiers: string[]
|
||||
}
|
||||
|
||||
export type ClassEntry = [string, ClassMetadata]
|
||||
|
||||
const IS_FRACTION = /^\d+\/\d+$/
|
||||
|
||||
export function getClassList(design: DesignSystem): ClassEntry[] {
|
||||
let list: [string, ClassMetadata][] = []
|
||||
let list: ClassItem[] = []
|
||||
|
||||
// Static utilities only work as-is
|
||||
for (let utility of design.utilities.keys('static')) {
|
||||
list.push([utility, { modifiers: [] }])
|
||||
list.push({
|
||||
name: utility,
|
||||
utility,
|
||||
fraction: false,
|
||||
modifiers: [],
|
||||
})
|
||||
}
|
||||
|
||||
// Functional utilities have their own list of completions
|
||||
@ -23,20 +38,99 @@ export function getClassList(design: DesignSystem): ClassEntry[] {
|
||||
|
||||
for (let group of completions) {
|
||||
for (let value of group.values) {
|
||||
let fraction = value !== null && IS_FRACTION.test(value)
|
||||
|
||||
let name = value === null ? utility : `${utility}-${value}`
|
||||
|
||||
list.push([name, { modifiers: group.modifiers }])
|
||||
list.push({
|
||||
name,
|
||||
utility,
|
||||
fraction,
|
||||
modifiers: group.modifiers,
|
||||
})
|
||||
|
||||
if (group.supportsNegative) {
|
||||
list.push([`-${name}`, { modifiers: group.modifiers }])
|
||||
list.push({
|
||||
name: `-${name}`,
|
||||
utility: `-${utility}`,
|
||||
fraction,
|
||||
modifiers: group.modifiers,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list.sort((a, b) => compare(a[0], b[0]))
|
||||
if (list.length === 0) return []
|
||||
|
||||
return list
|
||||
// Sort utilities by their class name
|
||||
list.sort((a, b) => compare(a.name, b.name))
|
||||
|
||||
let entries = sortFractionsLast(list)
|
||||
|
||||
return entries
|
||||
}
|
||||
|
||||
function sortFractionsLast(list: ClassItem[]) {
|
||||
type Bucket = {
|
||||
utility: string
|
||||
items: ClassItem[]
|
||||
}
|
||||
|
||||
// 1. Create "buckets" for each utility group
|
||||
let buckets: Bucket[] = []
|
||||
let current: Bucket | null = null
|
||||
|
||||
// 2. Determine the last bucket for each utility group
|
||||
let lastUtilityBucket = new Map<string, Bucket>()
|
||||
|
||||
// 3. Collect all fractions in a given utility group
|
||||
let fractions = new DefaultMap<string, ClassItem[]>(() => [])
|
||||
|
||||
for (let item of list) {
|
||||
let { utility, fraction } = item
|
||||
|
||||
if (!current) {
|
||||
current = { utility, items: [] }
|
||||
lastUtilityBucket.set(utility, current)
|
||||
}
|
||||
|
||||
if (utility !== current.utility) {
|
||||
buckets.push(current)
|
||||
|
||||
current = { utility, items: [] }
|
||||
lastUtilityBucket.set(utility, current)
|
||||
}
|
||||
|
||||
if (fraction) {
|
||||
fractions.get(utility).push(item)
|
||||
} else {
|
||||
current.items.push(item)
|
||||
}
|
||||
}
|
||||
|
||||
if (current && buckets[buckets.length - 1] !== current) {
|
||||
buckets.push(current)
|
||||
}
|
||||
|
||||
// 4. Add fractions to their respective last utility buckets
|
||||
for (let [utility, items] of fractions) {
|
||||
let bucket = lastUtilityBucket.get(utility)
|
||||
if (!bucket) continue
|
||||
|
||||
bucket.items.push(...items)
|
||||
}
|
||||
|
||||
// 5. Flatten the buckets into a single list
|
||||
let entries: ClassEntry[] = []
|
||||
|
||||
for (let bucket of buckets) {
|
||||
for (let entry of bucket.items) {
|
||||
entries.push([entry.name, { modifiers: entry.modifiers }])
|
||||
}
|
||||
}
|
||||
|
||||
return entries
|
||||
}
|
||||
|
||||
interface SelectorOptions {
|
||||
|
||||
@ -42,6 +42,7 @@ type SuggestionDefinition =
|
||||
| string
|
||||
| {
|
||||
supportsNegative?: boolean
|
||||
supportsFractions?: boolean
|
||||
values?: string[]
|
||||
modifiers?: string[]
|
||||
valueThemeKeys?: ThemeKey[]
|
||||
@ -225,6 +226,35 @@ export function createUtilities(theme: Theme) {
|
||||
}
|
||||
}
|
||||
|
||||
let suggestedFractions = [
|
||||
'1/2',
|
||||
'1/3',
|
||||
'2/3',
|
||||
'1/4',
|
||||
'2/4',
|
||||
'3/4',
|
||||
'1/5',
|
||||
'2/5',
|
||||
'3/5',
|
||||
'4/5',
|
||||
'1/6',
|
||||
'2/6',
|
||||
'3/6',
|
||||
'4/6',
|
||||
'5/6',
|
||||
'1/12',
|
||||
'2/12',
|
||||
'3/12',
|
||||
'4/12',
|
||||
'5/12',
|
||||
'6/12',
|
||||
'7/12',
|
||||
'8/12',
|
||||
'9/12',
|
||||
'10/12',
|
||||
'11/12',
|
||||
]
|
||||
|
||||
utilities.suggest(classRoot, () => {
|
||||
let groups: SuggestionGroup[] = []
|
||||
|
||||
@ -238,8 +268,13 @@ export function createUtilities(theme: Theme) {
|
||||
...(defn.values ?? []),
|
||||
...resolve(defn.valueThemeKeys ?? []),
|
||||
]
|
||||
|
||||
let modifiers = [...(defn.modifiers ?? []), ...resolve(defn.modifierThemeKeys ?? [])]
|
||||
|
||||
if (defn.supportsFractions) {
|
||||
values.push(...suggestedFractions)
|
||||
}
|
||||
|
||||
if (defn.hasDefaultValue) {
|
||||
values.unshift(null)
|
||||
}
|
||||
@ -341,6 +376,7 @@ export function createUtilities(theme: Theme) {
|
||||
supportsNegative: desc.supportsNegative,
|
||||
valueThemeKeys: desc.themeKeys ?? [],
|
||||
hasDefaultValue: desc.defaultValue !== undefined && desc.defaultValue !== null,
|
||||
supportsFractions: desc.supportsFractions,
|
||||
},
|
||||
])
|
||||
}
|
||||
@ -467,6 +503,7 @@ export function createUtilities(theme: Theme) {
|
||||
]
|
||||
: [],
|
||||
supportsNegative,
|
||||
supportsFractions,
|
||||
valueThemeKeys: themeKeys,
|
||||
},
|
||||
])
|
||||
@ -966,6 +1003,8 @@ export function createUtilities(theme: Theme) {
|
||||
}
|
||||
})
|
||||
|
||||
suggest('flex', () => [{ supportsFractions: true }])
|
||||
|
||||
/**
|
||||
* @css `flex-shrink`
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user