diff --git a/src/lib/completions.ts b/src/lib/completions.ts index f6f958a..ae5da7e 100644 --- a/src/lib/completions.ts +++ b/src/lib/completions.ts @@ -346,7 +346,7 @@ export function registerCompletions(ctx: ExtensionContext, core: Core): Disposab for (const attr of parser.parseAttrs()) { if (isAttrUtility(attr.key)) { - // inset decoration in bg|text|... = "..." + // insert decoration in bg|text|... = "..." const regex = /\S+/igm; const data = attr.value.raw; let match; @@ -357,7 +357,7 @@ export function registerCompletions(ctx: ExtensionContext, core: Core): Disposab } } } else if (['class', 'className'].includes(attr.key) || isAttrVariant(attr.key)) { - // inset decoration in class|className|sm|hover|... = "..." + // insert decoration in class|className|sm|hover|... = "..." const elements = new ClassParser(attr.value.raw, core.processor?.config('separator', ':') as string, Object.keys(core.variants)).parse(false); for (const element of elements) { if (element.type === 'group' && Array.isArray(element.content)) { @@ -372,6 +372,21 @@ export function registerCompletions(ctx: ExtensionContext, core: Core): Disposab } } + // insert decoration in @apply ... + for (const className of parser.parseApplies()) { + const elements = new ClassParser(className.result, core.processor?.config('separator', ':') as string, Object.keys(core.variants)).parse(false); + for (const element of elements) { + if (element.type === 'group' && Array.isArray(element.content)) { + for (const e of element.content) { + const color = isValidColor(e.raw); + if(color) colors.push(createColor(document, className.start, e.start, color)); + } + } + const color = element.type === 'utility' && isValidColor(element.raw); + if(color) colors.push(createColor(document, className.start, element.start, color)); + } + } + return colors; }, provideColorPresentations: () => { diff --git a/src/utils/parser.ts b/src/utils/parser.ts index 86f0136..6629561 100644 --- a/src/utils/parser.ts +++ b/src/utils/parser.ts @@ -1,4 +1,5 @@ export type Attr = { raw: string, key: string, value: { raw: string, start: number }, start: number, end: number }; +export type ClassName = { result: string, start: number, end: number }; export class HTMLParser { html?: string; @@ -39,7 +40,7 @@ export class HTMLParser { return output; } - parseClasses(): { start: number; end: number; result: string }[] { + parseClasses(): ClassName[] { // Match all class properties if (!this.html) return []; const classRegex = /\s(?:class|className|w:dark|w:light|w:active|w:after|w:before|w:checked|w:disabled|w:focus|w:hover|w:tw)=(["'])([^{}]+)\1/; @@ -67,4 +68,21 @@ export class HTMLParser { } return classNames; } + + parseApplies(): ClassName[] { + if (!this.html) return []; + const output: ClassName[] = []; + const regex = /(?<=@apply\s+)[^;]+(?=\s+!important)|(?<=@apply\s+)[^;]+(?=;)/igm; + let match; + while ((match = regex.exec(this.html as string))) { + if (match) { + output.push({ + result: this.html.slice(match.index, regex.lastIndex), + start: match.index, + end: regex.lastIndex, + }); + } + } + return output; + } }