fix @variants completions/diagnostics in JIT mode (fixes #324)
parent
533c2a0a91
commit
4cee488fb4
|
@ -176,16 +176,13 @@ function classNameToAst(
|
||||||
let context = meta.context
|
let context = meta.context
|
||||||
let pseudo = meta.pseudo
|
let pseudo = meta.pseudo
|
||||||
const globalContexts = state.classNames.context
|
const globalContexts = state.classNames.context
|
||||||
let screens = dlv(state.config, 'theme.screens', dlv(state.config, 'screens', {}))
|
|
||||||
if (!isObject(screens)) screens = {}
|
|
||||||
screens = Object.keys(screens)
|
|
||||||
const path = []
|
const path = []
|
||||||
|
|
||||||
for (let i = 0; i < classNameParts.length - 1; i++) {
|
for (let i = 0; i < classNameParts.length - 1; i++) {
|
||||||
let part = classNameParts[i]
|
let part = classNameParts[i]
|
||||||
let common = globalContexts[part]
|
let common = globalContexts[part]
|
||||||
if (!common) return null
|
if (!common) return null
|
||||||
if (screens.includes(part)) {
|
if (state.screens.includes(part)) {
|
||||||
path.push(`@screen ${part}`)
|
path.push(`@screen ${part}`)
|
||||||
context = context.filter((con) => !common.includes(con))
|
context = context.filter((con) => !common.includes(con))
|
||||||
}
|
}
|
||||||
|
|
|
@ -633,11 +633,17 @@ function provideVariantsDirectiveCompletions(
|
||||||
|
|
||||||
if (/\s+/.test(parts[parts.length - 1])) return null
|
if (/\s+/.test(parts[parts.length - 1])) return null
|
||||||
|
|
||||||
|
let possibleVariants = Object.keys(state.variants)
|
||||||
const existingVariants = parts.slice(0, parts.length - 1)
|
const existingVariants = parts.slice(0, parts.length - 1)
|
||||||
|
|
||||||
|
if (state.jit) {
|
||||||
|
possibleVariants.unshift('responsive')
|
||||||
|
possibleVariants = possibleVariants.filter((v) => !state.screens.includes(v))
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isIncomplete: false,
|
isIncomplete: false,
|
||||||
items: Object.keys(state.variants)
|
items: possibleVariants
|
||||||
.filter((v) => existingVariants.indexOf(v) === -1)
|
.filter((v) => existingVariants.indexOf(v) === -1)
|
||||||
.map((variant, index) => ({
|
.map((variant, index) => ({
|
||||||
// TODO: detail
|
// TODO: detail
|
||||||
|
|
|
@ -31,16 +31,14 @@ export function getInvalidScreenDiagnostics(
|
||||||
let text = document.getText(range)
|
let text = document.getText(range)
|
||||||
let matches = findAll(/(?:\s|^)@screen\s+(?<screen>[^\s{]+)/g, text)
|
let matches = findAll(/(?:\s|^)@screen\s+(?<screen>[^\s{]+)/g, text)
|
||||||
|
|
||||||
let screens = Object.keys(dlv(state.config, 'theme.screens', dlv(state.config, 'screens', {})))
|
|
||||||
|
|
||||||
matches.forEach((match) => {
|
matches.forEach((match) => {
|
||||||
if (screens.includes(match.groups.screen)) {
|
if (state.screens.includes(match.groups.screen)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
let message = `The screen '${match.groups.screen}' does not exist in your theme config.`
|
let message = `The screen '${match.groups.screen}' does not exist in your theme config.`
|
||||||
let suggestions: string[] = []
|
let suggestions: string[] = []
|
||||||
let suggestion = closest(match.groups.screen, screens)
|
let suggestion = closest(match.groups.screen, state.screens)
|
||||||
|
|
||||||
if (suggestion) {
|
if (suggestion) {
|
||||||
suggestions.push(suggestion)
|
suggestions.push(suggestion)
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { getLanguageBoundaries } from '../util/getLanguageBoundaries'
|
||||||
import { findAll, indexToPosition } from '../util/find'
|
import { findAll, indexToPosition } from '../util/find'
|
||||||
import { closest } from '../util/closest'
|
import { closest } from '../util/closest'
|
||||||
import { absoluteRange } from '../util/absoluteRange'
|
import { absoluteRange } from '../util/absoluteRange'
|
||||||
|
import dlv from 'dlv'
|
||||||
|
|
||||||
export function getInvalidVariantDiagnostics(
|
export function getInvalidVariantDiagnostics(
|
||||||
state: State,
|
state: State,
|
||||||
|
@ -26,6 +27,12 @@ export function getInvalidVariantDiagnostics(
|
||||||
ranges.push(...boundaries.css)
|
ranges.push(...boundaries.css)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let possibleVariants = Object.keys(state.variants)
|
||||||
|
if (state.jit) {
|
||||||
|
possibleVariants.unshift('responsive')
|
||||||
|
possibleVariants = possibleVariants.filter((v) => !state.screens.includes(v))
|
||||||
|
}
|
||||||
|
|
||||||
ranges.forEach((range) => {
|
ranges.forEach((range) => {
|
||||||
let text = document.getText(range)
|
let text = document.getText(range)
|
||||||
let matches = findAll(/(?:\s|^)@variants\s+(?<variants>[^{]+)/g, text)
|
let matches = findAll(/(?:\s|^)@variants\s+(?<variants>[^{]+)/g, text)
|
||||||
|
@ -36,13 +43,13 @@ export function getInvalidVariantDiagnostics(
|
||||||
|
|
||||||
for (let i = 0; i < variants.length; i += 2) {
|
for (let i = 0; i < variants.length; i += 2) {
|
||||||
let variant = variants[i].trim()
|
let variant = variants[i].trim()
|
||||||
if (Object.keys(state.variants).includes(variant)) {
|
if (possibleVariants.includes(variant)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
let message = `The variant '${variant}' does not exist.`
|
let message = `The variant '${variant}' does not exist.`
|
||||||
let suggestions: string[] = []
|
let suggestions: string[] = []
|
||||||
let suggestion = closest(variant, Object.keys(state.variants))
|
let suggestion = closest(variant, possibleVariants)
|
||||||
|
|
||||||
if (suggestion) {
|
if (suggestion) {
|
||||||
suggestions.push(suggestion)
|
suggestions.push(suggestion)
|
||||||
|
|
|
@ -70,6 +70,7 @@ export interface State {
|
||||||
separator?: string
|
separator?: string
|
||||||
dependencies?: string[]
|
dependencies?: string[]
|
||||||
plugins?: any
|
plugins?: any
|
||||||
|
screens?: string[]
|
||||||
variants?: Record<string, string | null>
|
variants?: Record<string, string | null>
|
||||||
modules?: {
|
modules?: {
|
||||||
tailwindcss?: { version: string; module: any }
|
tailwindcss?: { version: string; module: any }
|
||||||
|
|
|
@ -712,9 +712,11 @@ async function createProjectService(
|
||||||
state.separator = typeof userSeperator === 'string' ? userSeperator : ':'
|
state.separator = typeof userSeperator === 'string' ? userSeperator : ':'
|
||||||
state.plugins = await getPlugins(config)
|
state.plugins = await getPlugins(config)
|
||||||
state.classNames = (await extractClassNames(postcssResult.root)) as ClassNames
|
state.classNames = (await extractClassNames(postcssResult.root)) as ClassNames
|
||||||
|
|
||||||
state.variants = getVariants(state)
|
state.variants = getVariants(state)
|
||||||
|
|
||||||
|
let screens = dlv(state.config, 'theme.screens', dlv(state.config, 'screens', {}))
|
||||||
|
state.screens = isObject(screens) ? Object.keys(screens) : []
|
||||||
|
|
||||||
state.enabled = true
|
state.enabled = true
|
||||||
|
|
||||||
updateAllDiagnostics(state)
|
updateAllDiagnostics(state)
|
||||||
|
|
Loading…
Reference in New Issue