aliaset
Version:
twind monorepo
169 lines (151 loc) • 6.58 kB
text/typescript
// @vitest-environment happy-dom
import { assert, test } from 'vitest'
import presetTailwind from '@twind/preset-tailwind'
import { twind, virtual, observe, inline, getSheet } from '..'
test('observe in browser', () => {
document.documentElement.innerHTML = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body class="!block" style="display: none">
<main class="h-screen bg-purple-400 flex items-center justify-center">
<h1 class="font-bold /* you can even use inline comments */ text-(center 5xl white sm:gray-800 md:pink-700)">
This is Twind!
</h1>
</main>
</body>
</html>
`
const tw = observe(twind({ presets: [presetTailwind({ disablePreflight: true })] }, virtual()))
assert.deepEqual(tw.target, [
'.text-white{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity))}',
'.\\!block{display:block !important}',
'.flex{display:flex}',
'.h-screen{height:100vh}',
'.bg-purple-400{--tw-bg-opacity:1;background-color:rgba(192,132,252,var(--tw-bg-opacity))}',
'.text-5xl{font-size:3rem;line-height:1}',
'.font-bold{font-weight:700}',
'.items-center{align-items:center}',
'.justify-center{justify-content:center}',
'.text-center{text-align:center}',
'@media (min-width:640px){.sm\\:text-gray-800{--tw-text-opacity:1;color:rgba(31,41,55,var(--tw-text-opacity))}}',
'@media (min-width:768px){.md\\:text-pink-700{--tw-text-opacity:1;color:rgba(190,24,93,var(--tw-text-opacity))}}',
])
assert.strictEqual(
document.body.innerHTML.trim(),
`
<main class="h-screen bg-purple-400 flex items-center justify-center">
<h1 class="text-white text-5xl font-bold text-center sm:text-gray-800 md:text-pink-700">
This is Twind!
</h1>
</main>
`.trim(),
)
tw.clear()
// ensure tw is callable
assert.strictEqual(tw('underline'), 'underline')
assert.deepEqual(tw.target, ['.underline{text-decoration-line:underline}'])
// ensure the observer is disconnected on destroy
tw.destroy()
// the stylesheet is emptied
assert.lengthOf(tw.target, 0)
// attributes are no longer modified
;(document.querySelector('main') as Element).className = '~(text-3xl bg-gray-100)'
// the stylesheet is emptied
assert.lengthOf(tw.target, 0)
assert.strictEqual(document.querySelector('main')?.className, '~(text-3xl bg-gray-100)')
// TODO these do not work right now - bug in happy-dom?
// TODO Update attribute
// Update childList
// ;(document.querySelector('main') as HTMLElement).innerHTML = `
// <h1 class="font-bold text-(center 5xl white sm:gray-800 md:pink-700) after:content-['xxx']">
// This is <span class=font-(bold,sans)>Twind</span>!
// </h1>
// `
// assert.strictEqual(
// document.body.innerHTML.trim(),
// `
// <main class="h-screen bg-purple-400 flex items-center justify-center">
// <h1 class="text-white text-5xl font-bold text-center after:content-['xxx'] sm:text-gray-800 md:text-pink-700">
// This is <span class="font-bold font-sans">Twind</span>!
// </h1>
// </main>
// `.trim(),
// )
// assert.deepEqual(tw.target, [
// '.text-white{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity))}',
// '.\\!block{display:block !important}',
// '.flex{display:flex}',
// '.h-screen{height:100vh}',
// '.bg-purple-400{--tw-bg-opacity:1;background-color:rgba(192,132,252,var(--tw-bg-opacity))}',
// '.text-5xl{font-size:3rem;line-height:1}',
// '.font-bold{font-weight:700}',
// '.font-sans{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}',
// '.items-center{align-items:center}',
// '.justify-center{justify-content:center}',
// '.text-center{text-align:center}',
// ".after\\:content-\\[\\'xxx\\'\\]:after{--tw-content:'xxx';content:var(--tw-content)}",
// '@media (min-width:640px){.sm\\:text-gray-800{--tw-text-opacity:1;color:rgba(31,41,55,var(--tw-text-opacity))}}',
// '@media (min-width:768px){.md\\:text-pink-700{--tw-text-opacity:1;color:rgba(190,24,93,var(--tw-text-opacity))}}',
// ])
})
test('hydratable from SSR sheet', () => {
// render SSR sheet
document.documentElement.innerHTML = inline(
`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body class="!block" style="display: none">
<main class="h-screen bg-purple-400 flex items-center justify-center">
<h1 class="font-bold /* you can even use inline comments */ text-(center 5xl white sm:gray-800 md:pink-700)">
This is Twind!
</h1>
</main>
</body>
</html>
`,
{
tw: twind(
{ presets: [presetTailwind({ disablePreflight: true })] },
virtual(true /* includeHydrationInfos */),
),
},
)
assert.include(
document.documentElement.innerHTML,
'<style data-twind="">/*!dbgidc,t,text-white*/.text-white{',
)
// test resumeable sheets
const tw = observe(
twind(
{ presets: [presetTailwind({ disablePreflight: true })] },
getSheet(true /* useDOMSheet */),
),
)
assert.deepEqual(
Array.from((tw.target as HTMLStyleElement).childNodes, (node) => node.textContent),
[
'.text-white{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity))}',
'.\\!block{display:block !important}',
'.flex{display:flex}',
'.h-screen{height:100vh}',
'.bg-purple-400{--tw-bg-opacity:1;background-color:rgba(192,132,252,var(--tw-bg-opacity))}',
'.text-5xl{font-size:3rem;line-height:1}',
'.font-bold{font-weight:700}',
'.items-center{align-items:center}',
'.justify-center{justify-content:center}',
'.text-center{text-align:center}',
'@media (min-width:640px){.sm\\:text-gray-800{--tw-text-opacity:1;color:rgba(31,41,55,var(--tw-text-opacity))}}',
'@media (min-width:768px){.md\\:text-pink-700{--tw-text-opacity:1;color:rgba(190,24,93,var(--tw-text-opacity))}}',
],
)
})