Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/declaration-value-checks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'zyzz': patch
---

Improved type-checking performance of configured `style` and `variants` further. Declaration values are now checked directly per property instead of through one-key objects, and lengths skip unit parsing unless a range rule needs it: about 12% fewer instantiations and 8% faster checks on a large app, and up to 35% fewer instantiations per call with the default theme. Accepted inputs and diagnostics are unchanged.
35 changes: 31 additions & 4 deletions src/Config.bench-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ bench('create / token-free authoring', () => {

style({ color: '#fff', padding: '8px' })
script()
}).types([16414, 'instantiations'])
}).types([8783, 'instantiations'])

bench('create / inline theme with layers and shorthands', () => {
const { style, vars: theme } = Config.create({
Expand All @@ -38,7 +38,7 @@ bench('create / inline theme with layers and shorthands', () => {
':hover': { color: theme.color.brand },
margin: 'md',
})
}).types([47664, 'instantiations'])
}).types([16866, 'instantiations'])

bench('create / named theme catalog', () => {
const base = Vars.define({
Expand All @@ -58,7 +58,7 @@ bench('create / named theme catalog', () => {

style({ color: 'brand', padding: 'md' })
themes({ colorScheme: 'dark', set: 'mint' })
}).types([108537, 'instantiations'])
}).types([9538, 'instantiations'])

bench('create / html output', () => {
const { style } = Config.create({ output: 'html' })
Expand All @@ -68,4 +68,31 @@ bench('create / html output', () => {

void style({ padding: '8px' })().class
void dynamic({ width: '25%' }).style
}).types([21682, 'instantiations'])
}).types([10954, 'instantiations'])

bench('create / configured styles with shorthands', () => {
const { style } = Config.create({
layers: ['base', 'components'],
shorthands: {
px: ['paddingLeft', 'paddingRight'],
py: ['paddingTop', 'paddingBottom'],
},
vars: {
color: { border: '#ddd', ink: '#111', muted: '#666', surface: '#fff' },
radius: { md: '6px', sm: '4px' },
spacing: { 1: '4px', 2: '8px', 3: '12px', 4: '16px' },
},
})

style({
'@layer components': { borderRadius: 'md', px: 3, py: 2 },
':hover': { backgroundColor: 'muted' },
alignItems: 'center',
backgroundColor: 'surface',
borderColor: 'border',
color: 'ink',
display: 'flex',
gap: 2,
})
style({ color: 'ink', display: 'flex', gap: 2, px: 4 })
}).types([46652, 'instantiations'])
8 changes: 4 additions & 4 deletions src/Style.bench-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ bench('define / literal named styles', () => {
hidden: { display: 'none' },
label: { color: '#111', fontSize: '14px', lineHeight: 1.5 },
})
}).types([26868, 'instantiations'])
}).types([14158, 'instantiations'])

bench('define / nested conditions', () => {
Style.define({
Expand All @@ -39,7 +39,7 @@ bench('define / nested conditions', () => {
padding: '0.5rem 1rem',
},
})
}).types([11024, 'instantiations'])
}).types([5977, 'instantiations'])

bench('define / compound declarations', () => {
Style.define({
Expand All @@ -51,7 +51,7 @@ bench('define / compound declarations', () => {
transition: 'opacity 200ms ease-in',
},
})
}).types([262988, 'instantiations'])
}).types([103288, 'instantiations'])

bench('define / theme shorthand names', () => {
const theme = Vars.define({
Expand All @@ -66,4 +66,4 @@ bench('define / theme shorthand names', () => {
},
{ vars: theme },
)
}).types([63356, 'instantiations'])
}).types([65397, 'instantiations'])
9 changes: 5 additions & 4 deletions src/Style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,14 @@ type AcceptedMember<
: // Naming the expected tokens avoids a `never` diagnostic and keeps completions to accepted values.
[Value.Tokens<value, tokens, key>] extends [never]
? Value.Mismatch<tokens, key>
: Value.Accepted<
Record<key, value>,
: Value.AcceptedValue<
value,
key,
literal extends true
? LiteralDeclarations
: DeclarationProperties<tokens>
>[key] &
Value.Checked<Record<key, value>, tokens>[key] &
> &
Value.CheckedValue<value, key, tokens> &
Value.Tokens<value, tokens, key>
: key extends Condition.Keys<tokens, key>
? [value] extends [undefined]
Expand Down
8 changes: 4 additions & 4 deletions src/Theme.bench-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ bench('define / scalar and scheme tokens', () => {
spacing: { 4: '1rem', 8: '2rem', md: '8px' },
textColor: { foreground: '#000' },
})
}).types([142641, 'instantiations'])
}).types([3567, 'instantiations'])

bench('define / query aliases', () => {
const theme = Vars.define({
Expand All @@ -41,7 +41,7 @@ bench('define / query aliases', () => {
'@container sidebar >=card': { display: 'grid' },
'@media tablet..desktop': { ':hover': { padding: 'gap' } },
})
}).types([24193, 'instantiations'])
}).types([15333, 'instantiations'])

bench('extend / overrides', () => {
const theme = Vars.define({
Expand All @@ -54,7 +54,7 @@ bench('extend / overrides', () => {
backgroundColor: { surface: '#fff' },
spacing: { md: '2rem' },
})
}).types([39162, 'instantiations'])
}).types([13216, 'instantiations'])

bench('style / token names and references', () => {
const theme = Vars.define({
Expand All @@ -69,4 +69,4 @@ bench('style / token names and references', () => {
padding: 4,
width: theme.spacing[4],
})
}).types([49914, 'instantiations'])
}).types([16131, 'instantiations'])
4 changes: 2 additions & 2 deletions src/base-ui/react/Style.bench-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ bench('base ui / presence and valued states', () => {
style(Select.Popup, {
states: { side: { bottom: { marginTop: '8px' } } },
})
}).types([13525, 'instantiations'])
}).types([12733, 'instantiations'])

bench('base ui / configured states', () => {
const { style } = defineConfig({
Expand All @@ -35,4 +35,4 @@ bench('base ui / configured states', () => {
px: 'gap',
states: { highlighted: { color: 'accent', px: 'gap' } },
})
}).types([46987, 'instantiations'])
}).types([21498, 'instantiations'])
2 changes: 1 addition & 1 deletion src/compiler/Source.bench-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ bench('extract / styles, calls, and themes', () => {
void result.calls[0]?.name
void result.styles.styles[0]?.declarations
void result.vars.base?.className
}).types([41, 'instantiations'])
}).types([42, 'instantiations'])
2 changes: 1 addition & 1 deletion src/cx.bench-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ bench('cx / ordered static props', () => {
const a = style({ padding: '8px', color: 'red' })
const b = style({ paddingLeft: '12px', color: 'blue' })
cx(a(), false, null, undefined, b(), a())
}).types([30418, 'instantiations'])
}).types([18018, 'instantiations'])
100 changes: 100 additions & 0 deletions src/default.bench-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* Measures type instantiations of app-scale authoring against the bundled default theme,
* whose token set is comparable to a production design system.
* @module
*/
import { bench } from '@ark/attest'
import type * as Default from 'zyzz/default'

// Type-only imports keep the fixture free of runtime module loading; attest
// analyzes bench bodies without executing them.
declare const style: typeof Default.style
declare const variants: typeof Default.variants

/** Resolves the theme's token domains before any bench body is measured. */
export function baseline() {
style({ color: 'gray.100', padding: 4 })
variants({ base: { color: 'gray.100' } })
}

bench('default / token declarations', () => {
style({
alignItems: 'center',
backgroundColor: 'background.primary',
borderColor: 'gray.400',
borderRadius: 'md',
color: 'gray.1000',
display: 'flex',
gap: 2,
paddingBlock: 1,
paddingInline: 3,
})
}).types([77285, 'instantiations'])

bench('default / mixed literal and token declarations', () => {
style({
borderWidth: '1px',
boxShadow: 'sm',
fontSize: 'sm',
fontWeight: 'medium',
height: 8,
margin: '0 auto !custom',
transition: 'transform 160ms cubic-bezier(0.34, 1.36, 0.64, 1) !custom',
width: 'calc(100% - 16px) !custom',
})
}).types([103991, 'instantiations'])

bench('default / nested conditions', () => {
style({
':hover': { backgroundColor: 'gray.200' },
':active': { backgroundColor: 'gray.300', transform: 'scale(0.97)' },
'&[aria-pressed="true"]': { color: 'blue.700' },
'@media >=md': {
padding: 4,
':focus-visible': { outlineColor: 'blue.700' },
},
color: 'gray.900',
padding: 2,
})
}).types([37498, 'instantiations'])

bench('default / repeated declarations', () => {
// Every app repeats declarations across styles; repeats should hit cached checks.
style({ color: 'gray.1000', display: 'flex', gap: 2, padding: 3 })
style({ color: 'gray.1000', display: 'flex', gap: 2, padding: 3 })
style({ color: 'gray.1000', display: 'flex', gap: 2, padding: 3 })
style({ color: 'gray.1000', display: 'flex', gap: 2, padding: 3 })
}).types([13945, 'instantiations'])

bench('default / recipe', () => {
const button = variants({
base: {
alignItems: 'center',
borderRadius: 'md',
display: 'inline-flex',
fontWeight: 'medium',
':hover:not(:disabled)': { backgroundColor: 'gray.200' },
},
variants: {
size: {
sm: { fontSize: 'xs', height: 7, paddingInline: 2 },
md: { fontSize: 'sm', height: 8, paddingInline: 3 },
lg: { fontSize: 'base', height: 10, paddingInline: 4 },
},
tone: {
neutral: { backgroundColor: 'background.primary', color: 'gray.1000' },
primary: { backgroundColor: 'gray.1000', color: 'background.primary' },
danger: { backgroundColor: 'red.100', color: 'red.900' },
},
},
defaultVariants: { size: 'md', tone: 'neutral' },
compoundVariants: [
{
when: { size: 'sm', tone: 'danger' },
style: { fontWeight: 'semibold' },
},
],
})

button({ size: 'lg', tone: 'primary' })
}).types([64905, 'instantiations'])
Loading
Loading