This module provides virtualSheet and domSheet which can be used with {@link twind.setup | setup}({ {@link twind.Configuration.sheet | sheet} })
.
The virtual sheet collects style rules into an array. This is most useful during testing and {@page Extract Styles aka SSR | server side rendering (SSR)}.
Additionally it provides an API to reset the current internal state of its tw
function.
💡 You can find detailed instructions and example in the {@page Extract Styles aka SSR | Server Side Rendering (SSR) guide}.
The following example assumes your app is using the tw
named export from twind
but the same logic can be applied to custom instances.
import { setup } from 'twind'
import { virtualSheet, getStyleTag } from 'twind/sheets'
const sheet = virtualSheet()
setup({ ...sharedOptions, sheet })
function ssr() {
// 1. Reset the sheet for a new rendering
sheet.reset()
// 2. Render the app
const body = renderTheApp()
// 3. Create the style tag with all generated CSS rules
const styleTag = getStyleTag(sheet)
// 4. Generate the response html
return `<!DOCTYPE html>
<html lang="en">
<head>${styleTag}</head>
<body>${body}</body>
</html>
`
}
💡 The example below uses uvu. Please adjust the test code to your testing framework.
import { suite } from 'uvu'
import * as assert from 'uvu/assert'
import { create } from 'twind'
import { virtualSheet } from 'twind/sheets'
const test = suite('using virtual sheet')
// Setup code to be run once before all tests
test.before((context) => {
context.sheet = virtualSheet()
const instance = create({
sheet: context.sheet,
// Fail tests on unknown rules or theme values
mode: 'strict',
// Prevent preflight rules to be added into sheet
preflight: false,
// Do not prefix properties and values
prefix: false,
})
context.tw = instance.tw
})
// Clear the state before each test
test.before.each(({ sheet }) => {
sheet.reset()
})
test('render one rule', ({ tw, sheet }) => {
assert.is(tw`text(center)`, 'text-center')
assert.equal(sheet.target, '.text-center{text-align:center}')
})
This sheet uses DOM Text nodes to insert the CSS rules into the stylesheet. Using DOM manipulation makes this way slower than the {@link twind.cssomSheet | default sheet} but allows to see the generated CSS in to DOM. Most modern browser display CSS rules from the speedy default sheet using their CSS inspector.
💡 In production it is advised to use {@link twind.cssomSheet | speedy default sheet}.
If the domSheet
is passed no target
it looks for an style element with the id __twind
. If no such element is found it will create one and append it to the document.head
.
import { setup } from 'twind'
import { domSheet } from 'twind/sheets'
setup({ ...sharedOptions, sheet: domSheet() })
In case the builtin sheet implementations do not solve your use case, you can create your own:
import { setup } from 'twind'
const customSheet = (target = []) => ({
target,
insert: (rule, index) => {
// rule: the CSS rule to insert
// index: the rule's position
target.splice(index, 0, rule)
},
})
setup({ ...sharedOptions, sheet: customSheet() })