Skip to content

Commit

Permalink
Avoid splitting class within arbitrary values
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-rogerson committed Sep 21, 2022
1 parent 59713cd commit b866af6
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 11 deletions.
9 changes: 3 additions & 6 deletions src/core/lib/convertClassName.ts
@@ -1,12 +1,11 @@
import replaceThemeValue from './util/replaceThemeValue'
import isShortCss from './util/isShortCss'
import splitOnFirst from './util/splitOnFirst'
import { splitAtTopLevelOnly } from './util/twImports'
import type { CoreContext } from 'core/types'
// eslint-disable-next-line import/no-relative-parent-imports
import { SPACE_ID, SPACE_ID_TEMP_ALL } from '../constants'

const SPLIT_COLON_AVOID_WITHIN_SQUARE_BRACKETS =
/:(?=(?:(?:(?!]).)*\[)|[^[\]]*$)/g
const ARBITRARY_VARIANTS = /(?<=\[)(.+?)(?=]:)/g
const ALL_COMMAS = /,/g

Expand All @@ -22,7 +21,7 @@ function convertShortCssToArbitraryProperty(
isShortCssOnly,
}: ConvertShortCssToArbitraryPropertyParameters
): string {
const splitArray = className.split(SPLIT_COLON_AVOID_WITHIN_SQUARE_BRACKETS)
const splitArray = [...splitAtTopLevelOnly(className, ':')]

const lastValue = splitArray.slice(-1)[0]

Expand Down Expand Up @@ -84,9 +83,7 @@ function convertClassName(
if (className.endsWith('!')) {
debug('trailing bang found', className)

const splitArray = className
.slice(0, -1)
.split(SPLIT_COLON_AVOID_WITHIN_SQUARE_BRACKETS)
const splitArray = [...splitAtTopLevelOnly(className.slice(0, -1), ':')]
// Place a ! before the class
splitArray.splice(-1, 1, `!${splitArray[splitArray.length - 1]}`)
className = splitArray.join(':')
Expand Down
7 changes: 7 additions & 0 deletions src/core/lib/util/twImports.ts
Expand Up @@ -16,6 +16,8 @@ import { default as resolveTailwindConfigRaw } from 'tailwindcss/lib/util/resolv
// @ts-expect-error Types added below
import { default as getAllConfigsRaw } from 'tailwindcss/lib/util/getAllConfigs'
// @ts-expect-error Types added below
import { splitAtTopLevelOnly as splitAtTopLevelOnlyRaw } from 'tailwindcss/lib/util/splitAtTopLevelOnly'
// @ts-expect-error Types added below
import unescapeRaw from 'postcss-selector-parser/dist/util/unesc'

const toPath = toPathRaw as (path: string[] | string) => string[]
Expand All @@ -37,6 +39,10 @@ const resolveTailwindConfig = resolveTailwindConfigRaw as (
const getAllConfigs = getAllConfigsRaw as (
config: Record<string, unknown[]>
) => TailwindConfig[]
const splitAtTopLevelOnly = splitAtTopLevelOnlyRaw as (
input: string,
separator: string
) => string[]
const unescape = unescapeRaw as (string: string) => string

export {
Expand All @@ -47,5 +53,6 @@ export {
transformThemeValue,
resolveTailwindConfig,
getAllConfigs,
splitAtTopLevelOnly,
unescape,
}
8 changes: 3 additions & 5 deletions src/suggestions/index.ts
Expand Up @@ -15,10 +15,7 @@ import type {
TailwindConfig,
} from './types'
// eslint-disable-next-line import/no-relative-parent-imports
import { createCoreContext, getStyles } from '../core'

const COLONS_OUTSIDE_BRACKETS =
/:(?=(?:(?:(?!\)).)*\()|[^()]*$)(?=(?:(?:(?!]).)*\[)|[^[\]]*$)/g
import { createCoreContext, getStyles, splitAtTopLevelOnly } from '../core'

const ALL_SPACE_IDS = /{{SPACE}}/g

Expand All @@ -36,6 +33,7 @@ function getVariantSuggestions(
context: ClassErrorContext
): string | undefined {
const coreContext = createCoreContext({
tailwindConfig: context?.tailwindConfig,
CustomError: MacroError as typeof Error,
})
const { unmatched } = getStyles(className, coreContext)
Expand All @@ -60,7 +58,7 @@ function getVariantSuggestions(
function getClassError(rawClass: string, context: ClassErrorContext): string {
const input = rawClass.replace(ALL_SPACE_IDS, ' ')

const classPieces = input.split(COLONS_OUTSIDE_BRACKETS)
const classPieces = [...splitAtTopLevelOnly(input, ':')]

for (const validator of validators) {
const error = validator(classPieces, context)
Expand Down

0 comments on commit b866af6

Please sign in to comment.