Skip to content

Commit

Permalink
test: tailwind compat smoke test
Browse files Browse the repository at this point in the history
  • Loading branch information
sastan committed Dec 9, 2020
1 parent a62054d commit 619bcc8
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 2 deletions.
6 changes: 4 additions & 2 deletions packages/core/package.json
Expand Up @@ -42,16 +42,18 @@
},
"devDependencies": {
"@size-limit/preset-small-lib": "^4.6.0",
"dlv": "^1.1.3",
"nps": "^5.9.12",
"size-limit": "^4.6.0"
"size-limit": "^4.6.0",
"tailwindcss": "^2.0.1"
},
"publishConfig": {
"access": "public"
},
"size-limit": [
{
"path": "./dist/esnext/core.js",
"limit": "10.5 KB"
"limit": "11 KB"
}
]
}
8 changes: 8 additions & 0 deletions packages/core/src/__fixtures__/process-plugins.d.ts
@@ -0,0 +1,8 @@
export declare function processPlugins(): {
screens: Record<string, string>
variants: string[]
directives: Record<string, { selector: string; properties: Record<string, string> }>
darkMode: false | 'media' | 'class'
prefix: string
separator: string
}
145 changes: 145 additions & 0 deletions packages/core/src/__fixtures__/process-plugins.mjs
@@ -0,0 +1,145 @@
import dlv from 'dlv'

import corePlugins from 'tailwindcss/lib/corePlugins.js'
import resolveConfig from 'tailwindcss/lib/util/resolveConfig.js'
import defaultConfig from 'tailwindcss/stubs/defaultConfig.stub.js'
import transformThemeValue from 'tailwindcss/lib/util/transformThemeValue.js'

export function processPlugins() {
const config = resolveConfig([defaultConfig])

const plugins = [...corePlugins(config), ...dlv(config, 'plugins', [])]

const {
theme: { screens },
variantOrder: variants,
darkMode,
prefix,
separator,
} = config

// eslint-disable-next-line unicorn/consistent-function-scoping
const applyConfiguredPrefix = (selector) => selector

const getConfigValue = (path, defaultValue) => (path ? dlv(config, path, defaultValue) : config)

const utilities = {}

plugins.forEach((plugin) => {
if (plugin.__isOptionsFunction) {
plugin = plugin()
}

const handler = typeof plugin === 'function' ? plugin : dlv(plugin, 'handler', () => {})

handler({
// Postcss,
config: getConfigValue,

theme: (path, defaultValue) => {
const [pathRoot, ...subPaths] = path.split('.')

const value = getConfigValue(['theme', pathRoot, ...subPaths], defaultValue)

return transformThemeValue(pathRoot)(value)
},

corePlugins: (path) => {
if (Array.isArray(config.corePlugins)) {
return config.corePlugins.includes(path)
}

return getConfigValue(`corePlugins.${path}`, true)
},

variants: (path, defaultValue) => {
if (Array.isArray(config.variants)) {
return config.variants
}

return getConfigValue(`variants.${path}`, defaultValue)
},

// No escaping of class names as we use theme as directives
e: (className) => className,

prefix: applyConfiguredPrefix,

addUtilities: (newUtilities) => {
// => const defaultOptions = { variants: [], respectPrefix: true, respectImportant: true }

// options = Array.isArray(options)
// ? { ...defaultOptions, variants: options }
// : { ...defaultOptions, ...options }

// .directive => CSS rule
Object.assign(utilities, ...(Array.isArray(newUtilities) ? newUtilities : [newUtilities]))

// =>pluginUtilities.push(
// wrapWithLayer(wrapWithVariants(styles.nodes, options.variants), 'utilities'),
// )
},

addComponents: (newComponents, _options) => {
// => const defaultOptions = { variants: [], respectPrefix: true }
// options = Array.isArray(options)
// ? { ...defaultOptions, variants: options }
// : { ...defaultOptions, ...options }
// pluginComponents.push(
// wrapWithLayer(wrapWithVariants(styles.nodes, options.variants), 'components'),
// )
Object.assign(
utilities,
...(Array.isArray(newComponents) ? newComponents : [newComponents]),
)
},

addBase: (_baseStyles) => {
// => pluginBaseStyles.push(wrapWithLayer(parseStyles(baseStyles), 'base'))
},

addVariant: (_name, _generator, _options = {}) => {
// =>pluginVariantGenerators[name] = generateVariantFunction(generator, options)
},
})
})

const directives = {
group: { selector: '.group', properties: {} },
}

for (const selector of Object.keys(utilities)) {
// '@keyframes spin'
if (selector[0] === '@') {
continue
}

// '.ordinal, .slashed-zero, .lining-nums, .oldstyle-nums'
if (selector.includes(',')) {
continue
}

// '.placeholder-black::placeholder'
// '.divide-pink-50 > :not([hidden]) ~ :not([hidden])'
const [_, directive] = /^\.([^\s:]+)/.exec(selector) || []

if (directive) {
// Unescape
// '.w-4\\/5'
// '.space-x-2\\.5'
directives[directive.replace(/\\/g, '')] = {
selector,
properties: utilities[selector],
}
}
}

return {
screens,
variants,
directives,
darkMode,
prefix,
separator,
}
}
31 changes: 31 additions & 0 deletions packages/core/src/__tests__/tailwind-compat.test.ts
@@ -0,0 +1,31 @@
import { tw, setup, strict } from '..'

setup({ mode: strict })

test('all tailwind directives are available', async () => {
const { processPlugins } = await import('../__fixtures__/process-plugins')

const { directives } = processPlugins()

for (const directive of Object.keys(directives)) {
try {
expect(tw(directive)).toBeTruthy()
} catch (error) {
if (isFontVariantNumeric(directive)) {
// TODO https://tailwindcss.com/docs/font-variant-numeric
} else {
console.warn(directive, directives[directive])
throw error
}
}
}
})

function isFontVariantNumeric(directive: string): boolean {
return (
directive === 'ordinal' ||
directive.endsWith('-zero') ||
directive.endsWith('-nums') ||
directive.endsWith('-fractions')
)
}

0 comments on commit 619bcc8

Please sign in to comment.