import { expect, test } from 'vitest'
import { __unstable__loadDesignSystem } from '.'
import { buildDesignSystem } from './design-system'
import { Theme } from './theme'
const css = String.raw
function loadDesignSystem() {
let theme = new Theme()
theme.add('--spacing-0_5', '0.125rem')
theme.add('--spacing-1', '0.25rem')
theme.add('--spacing-3', '0.75rem')
theme.add('--spacing-4', '1rem')
theme.add('--width-4', '1rem')
theme.add('--colors-red-500', 'red')
theme.add('--colors-blue-500', 'blue')
theme.add('--breakpoint-sm', '640px')
theme.add('--font-size-xs', '0.75rem')
theme.add('--font-size-xs--line-height', '1rem')
theme.add('--perspective-dramatic', '100px')
theme.add('--perspective-normal', '500px')
theme.add('--opacity-background', '0.3')
return buildDesignSystem(theme)
}
test('getClassList', () => {
let design = loadDesignSystem()
let classList = design.getClassList()
let classNames = classList.flatMap(([name, meta]) => [
name,
...meta.modifiers.map((m) => `${name}/${m}`),
])
expect(classNames).toMatchSnapshot()
})
test('Theme values with underscores are converted back to decimal points', () => {
let design = loadDesignSystem()
let classes = design.getClassList()
expect(classes).toContainEqual(['inset-0.5', { modifiers: [] }])
})
test('getVariants', () => {
let design = loadDesignSystem()
let variants = design.getVariants()
expect(variants).toMatchSnapshot()
})
test('getVariants compound', () => {
let design = loadDesignSystem()
let variants = design.getVariants()
let group = variants.find((v) => v.name === 'group')!
let list = [
group.selectors({ value: 'hover' }),
group.selectors({ value: 'hover', modifier: 'sidebar' }),
group.selectors({ value: 'group-hover' }),
group.selectors({ value: 'sm' }),
group.selectors({ value: 'md' }),
]
expect(list).toEqual([
['&:is(:where(.group):hover *)'],
['&:is(:where(.group\\/sidebar):hover *)'],
['&:is(:where(.group):is(:where(.group):hover *) *)'],
[],
[],
])
})
test('The variant `has-force` does not crash', () => {
let design = loadDesignSystem()
let variants = design.getVariants()
let has = variants.find((v) => v.name === 'has')!
expect(has.selectors({ value: 'force' })).toMatchInlineSnapshot(`[]`)
})
test('Can produce CSS per candidate using `candidatesToCss`', () => {
let design = loadDesignSystem()
design.invalidCandidates = new Set(['bg-[#fff]'])
expect(design.candidatesToCss(['underline', 'i-dont-exist', 'bg-[#fff]', 'bg-[#000]']))
.toMatchInlineSnapshot(`
[
".underline {
text-decoration-line: underline;
}
",
null,
null,
".bg-\\[\\#000\\] {
background-color: #000;
}
",
]
`)
})
test('Utilities do not show wrapping selector in intellisense', async () => {
let input = css`
@import 'tailwindcss/utilities';
@config './config.js';
`
let design = await __unstable__loadDesignSystem(input, {
loadStylesheet: async (_, base) => ({
base,
content: '@tailwind utilities;',
}),
loadModule: async () => ({
base: '',
module: {
important: '#app',
},
}),
})
expect(design.candidatesToCss(['underline', 'hover:line-through'])).toMatchInlineSnapshot(`
[
".underline {
text-decoration-line: underline;
}
",
".hover\\:line-through {
&:hover {
@media (hover: hover) {
text-decoration-line: line-through;
}
}
}
",
]
`)
})
test('Utilities, when marked as important, show as important in intellisense', async () => {
let input = css`
@import 'tailwindcss/utilities' important;
`
let design = await __unstable__loadDesignSystem(input, {
loadStylesheet: async (_, base) => ({
base,
content: '@tailwind utilities;',
}),
})
expect(design.candidatesToCss(['underline', 'hover:line-through'])).toMatchInlineSnapshot(`
[
".underline {
text-decoration-line: underline!important;
}
",
".hover\\:line-through {
&:hover {
@media (hover: hover) {
text-decoration-line: line-through!important;
}
}
}
",
]
`)
})