Add global css() function for element/reset styles

This commit is contained in:
Chris Wanstrath 2026-03-11 13:15:38 -07:00
parent 8389a41c59
commit 239ad7459e
2 changed files with 89 additions and 1 deletions

View File

@ -318,5 +318,18 @@ function tagName(base: string): string {
return capitalized === 'A' ? 'Anchor' : capitalized
}
// global CSS for resets, element defaults, pseudo-elements
export function css(rules: Record<string, TagDef>) {
for (const [selector, def] of Object.entries(rules)) {
styles[selector] = makeStyle(def)
for (const [state, stateDef] of Object.entries(def.states ?? {}))
styles[`${selector}${stateName(state)}`] = makeStyle(stateDef)
}
injectStylesInBrowser()
}
// shortcut so you only have to import one thing, if you want
define.Styles = Styles
define.css = css

View File

@ -1,5 +1,5 @@
import { describe, test, expect } from 'bun:test'
import { define } from '../index'
import { define, css } from '../index'
import { renderToString, getStylesCSS, parseCSS } from './test_helpers'
describe('define - basic functionality', () => {
@ -1057,3 +1057,78 @@ describe('edge cases', () => {
expect(html).toContain('Second')
})
})
describe('css() - global styles', () => {
test('registers bare element selectors', () => {
css({
'body': { margin: 0, fontFamily: 'system-ui' }
})
const out = getStylesCSS()
expect(out).toContain('body {')
expect(out).toContain('font-family: system-ui')
expect(out).toContain('margin: 0px')
})
test('registers universal selector', () => {
css({
'*': { boxSizing: 'border-box' }
})
const out = getStylesCSS()
expect(out).toContain('* {')
expect(out).toContain('box-sizing: border-box')
})
test('registers compound selectors', () => {
css({
'*, *::before, *::after': { boxSizing: 'border-box' }
})
const out = getStylesCSS()
expect(out).toContain('*, *::before, *::after {')
})
test('registers pseudo-element selectors', () => {
css({
'::-webkit-scrollbar': { width: 8 }
})
const out = getStylesCSS()
expect(out).toContain('::-webkit-scrollbar {')
expect(out).toContain('width: 8px')
})
test('handles states on global selectors', () => {
css({
'a': {
color: 'blue',
states: {
hover: { color: 'darkblue' }
}
}
})
const out = getStylesCSS()
expect(out).toContain('a {')
expect(out).toContain('a:hover {')
expect(out).toContain('color: darkblue')
})
test('registers multiple selectors at once', () => {
css({
'html': { lineHeight: 1.5 },
'h1': { fontSize: 32 },
'p': { margin: 0 }
})
const out = getStylesCSS()
expect(out).toContain('html {')
expect(out).toContain('h1 {')
expect(out).toContain('p {')
})
test('accessible via define.css', () => {
expect(define.css).toBe(css)
})
})