@pyreon/styler 0.11.5 → 0.11.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +27 -23
  2. package/lib/index.d.ts +9 -2
  3. package/lib/index.js +47 -4
  4. package/package.json +22 -22
  5. package/src/ThemeProvider.ts +10 -3
  6. package/src/__tests__/ThemeProvider.test.ts +21 -21
  7. package/src/__tests__/benchmark.bench.ts +56 -45
  8. package/src/__tests__/composition-chain.test.ts +200 -151
  9. package/src/__tests__/forward.test.ts +122 -122
  10. package/src/__tests__/globalStyle.test.ts +18 -18
  11. package/src/__tests__/hash.test.ts +27 -27
  12. package/src/__tests__/hybrid-injection.test.ts +83 -59
  13. package/src/__tests__/index.ts +10 -10
  14. package/src/__tests__/insertion-effect.test.ts +45 -32
  15. package/src/__tests__/integration.test.ts +81 -51
  16. package/src/__tests__/keyframes.test.ts +13 -13
  17. package/src/__tests__/memory-growth.test.ts +21 -21
  18. package/src/__tests__/p3-features.test.ts +162 -104
  19. package/src/__tests__/shared.test.ts +51 -33
  20. package/src/__tests__/sheet-advanced.test.ts +227 -227
  21. package/src/__tests__/sheet-split-atrules.test.ts +85 -85
  22. package/src/__tests__/sheet.test.ts +69 -69
  23. package/src/__tests__/styled-ssr.test.ts +36 -28
  24. package/src/__tests__/styled.test.ts +214 -145
  25. package/src/__tests__/theme.test.ts +11 -11
  26. package/src/__tests__/useCSS.test.ts +89 -59
  27. package/src/css.ts +1 -1
  28. package/src/forward.ts +187 -187
  29. package/src/globalStyle.ts +5 -5
  30. package/src/index.ts +15 -15
  31. package/src/keyframes.ts +3 -3
  32. package/src/resolve.ts +14 -14
  33. package/src/shared.ts +2 -2
  34. package/src/sheet.ts +26 -26
  35. package/src/styled.tsx +145 -100
  36. package/src/useCSS.ts +4 -4
package/README.md CHANGED
@@ -71,7 +71,9 @@ const Text = styled('p')`
71
71
  Render as a different element at runtime:
72
72
 
73
73
  ```ts
74
- const Box = styled('div')`padding: 16px;`
74
+ const Box = styled('div')`
75
+ padding: 16px;
76
+ `
75
77
 
76
78
  // Renders as a <section>
77
79
  Box({ as: 'section', children: 'Content' })
@@ -83,7 +85,7 @@ Props prefixed with `$` are not forwarded to the DOM:
83
85
 
84
86
  ```ts
85
87
  const Box = styled('div')`
86
- color: ${(p) => p.$active ? 'blue' : 'gray'};
88
+ color: ${(p) => (p.$active ? 'blue' : 'gray')};
87
89
  `
88
90
 
89
91
  // $active is used for styling but won't appear on the <div>
@@ -122,10 +124,12 @@ Supports conditional patterns:
122
124
  ```ts
123
125
  const Box = styled('div')`
124
126
  display: flex;
125
- ${(props) => props.$bordered && css`
126
- border: 1px solid #e0e0e0;
127
- border-radius: 4px;
128
- `};
127
+ ${(props) =>
128
+ props.$bordered &&
129
+ css`
130
+ border: 1px solid #e0e0e0;
131
+ border-radius: 4px;
132
+ `};
129
133
  `
130
134
  ```
131
135
 
@@ -253,29 +257,29 @@ const Card = styled('div')`
253
257
 
254
258
  ### Bundle Size
255
259
 
256
- | Library | Minified | Gzipped |
257
- |---------|--------:|--------:|
258
- | goober | 2.32 KB | 1.31 KB |
259
- | **@pyreon/styler** | **10.13 KB** | **3.81 KB** |
260
- | styled-components | 44.93 KB | 17.89 KB |
261
- | @emotion/react + styled | 48.26 KB | 16.59 KB |
260
+ | Library | Minified | Gzipped |
261
+ | ----------------------- | -----------: | ----------: |
262
+ | goober | 2.32 KB | 1.31 KB |
263
+ | **@pyreon/styler** | **10.13 KB** | **3.81 KB** |
264
+ | styled-components | 44.93 KB | 17.89 KB |
265
+ | @emotion/react + styled | 48.26 KB | 16.59 KB |
262
266
 
263
267
  ### Performance (ops/sec, higher is better)
264
268
 
265
- | Benchmark | styler | styled-components | @emotion | goober |
266
- |-----------|-------:|-------------------:|---------:|-------:|
267
- | css() creation | **25.2M** | 9.0M | 2.2M | 26K |
268
- | css() with interpolations | **24.9M** | 5.6M | 2.3M | 28K |
269
- | Template resolution | **21.4M** | 3.9M | — | — |
270
- | Nested composition | **8.3M** | 2.2M | 1.4M | 8K |
271
- | SSR renderToString | **307K** | 69K | 192K | 18K |
272
- | styled() factory | **17.3M** | 109K | 933K | 18.2M |
269
+ | Benchmark | styler | styled-components | @emotion | goober |
270
+ | ------------------------- | --------: | ----------------: | -------: | -----: |
271
+ | css() creation | **25.2M** | 9.0M | 2.2M | 26K |
272
+ | css() with interpolations | **24.9M** | 5.6M | 2.3M | 28K |
273
+ | Template resolution | **21.4M** | 3.9M | — | — |
274
+ | Nested composition | **8.3M** | 2.2M | 1.4M | 8K |
275
+ | SSR renderToString | **307K** | 69K | 192K | 18K |
276
+ | styled() factory | **17.3M** | 109K | 933K | 18.2M |
273
277
 
274
278
  ## Peer Dependencies
275
279
 
276
- | Package | Version |
277
- | ------- | ------- |
278
- | @pyreon/core | >= 0.0.1 |
280
+ | Package | Version |
281
+ | ------------------ | -------- |
282
+ | @pyreon/core | >= 0.0.1 |
279
283
  | @pyreon/reactivity | >= 0.0.1 |
280
284
 
281
285
  ## License
package/lib/index.d.ts CHANGED
@@ -7,7 +7,14 @@ type Theme = DefaultTheme & Record<string, unknown>;
7
7
  declare const ThemeContext: _pyreon_core0.Context<Theme>;
8
8
  /** Hook to read the current theme from the nearest ThemeProvider. */
9
9
  declare const useTheme: <T extends object = Theme>() => T;
10
- /** Provides a theme object to all nested styled components via Pyreon context. */
10
+ /**
11
+ * @internal Low-level provider — use `PyreonUI` from `@pyreon/ui-core` instead.
12
+ *
13
+ * Provides a theme object to all nested styled components via Pyreon context.
14
+ *
15
+ * @deprecated Prefer `<PyreonUI theme={theme}>` which provides theme to
16
+ * all three context layers (styler, core, mode) in one component.
17
+ */
11
18
  declare function ThemeProvider({
12
19
  theme,
13
20
  children
@@ -201,7 +208,7 @@ interface StyledOptions {
201
208
  boost?: boolean;
202
209
  }
203
210
  type TagTemplateFn = (strings: TemplateStringsArray, ...values: Interpolation[]) => ComponentFn;
204
- type HtmlTags = "a" | "abbr" | "address" | "article" | "aside" | "audio" | "b" | "blockquote" | "body" | "br" | "button" | "canvas" | "caption" | "code" | "col" | "colgroup" | "dd" | "details" | "div" | "dl" | "dt" | "em" | "fieldset" | "figcaption" | "figure" | "footer" | "form" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "head" | "header" | "hr" | "html" | "i" | "iframe" | "img" | "input" | "label" | "legend" | "li" | "link" | "main" | "mark" | "menu" | "meta" | "nav" | "ol" | "optgroup" | "option" | "output" | "p" | "picture" | "pre" | "progress" | "q" | "section" | "select" | "small" | "source" | "span" | "strong" | "style" | "sub" | "summary" | "sup" | "svg" | "table" | "tbody" | "td" | "template" | "textarea" | "tfoot" | "th" | "thead" | "time" | "tr" | "u" | "ul" | "video";
211
+ type HtmlTags = 'a' | 'abbr' | 'address' | 'article' | 'aside' | 'audio' | 'b' | 'blockquote' | 'body' | 'br' | 'button' | 'canvas' | 'caption' | 'code' | 'col' | 'colgroup' | 'dd' | 'details' | 'div' | 'dl' | 'dt' | 'em' | 'fieldset' | 'figcaption' | 'figure' | 'footer' | 'form' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'head' | 'header' | 'hr' | 'html' | 'i' | 'iframe' | 'img' | 'input' | 'label' | 'legend' | 'li' | 'link' | 'main' | 'mark' | 'menu' | 'meta' | 'nav' | 'ol' | 'optgroup' | 'option' | 'output' | 'p' | 'picture' | 'pre' | 'progress' | 'q' | 'section' | 'select' | 'small' | 'source' | 'span' | 'strong' | 'style' | 'sub' | 'summary' | 'sup' | 'svg' | 'table' | 'tbody' | 'td' | 'template' | 'textarea' | 'tfoot' | 'th' | 'thead' | 'time' | 'tr' | 'u' | 'ul' | 'video';
205
212
  type StyledFunction = ((tag: Tag, options?: StyledOptions) => TagTemplateFn) & { [K in HtmlTags]: TagTemplateFn };
206
213
  declare const styled: StyledFunction;
207
214
  //#endregion
package/lib/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { createContext, h, provide, useContext } from "@pyreon/core";
2
+ import { effect } from "@pyreon/reactivity";
2
3
 
3
4
  //#region src/resolve.ts
4
5
  /**
@@ -689,7 +690,14 @@ const createSheet = (options) => new StyleSheet(options);
689
690
  const ThemeContext = createContext({});
690
691
  /** Hook to read the current theme from the nearest ThemeProvider. */
691
692
  const useTheme = () => useContext(ThemeContext);
692
- /** Provides a theme object to all nested styled components via Pyreon context. */
693
+ /**
694
+ * @internal Low-level provider — use `PyreonUI` from `@pyreon/ui-core` instead.
695
+ *
696
+ * Provides a theme object to all nested styled components via Pyreon context.
697
+ *
698
+ * @deprecated Prefer `<PyreonUI theme={theme}>` which provides theme to
699
+ * all three context layers (styler, core, mode) in one component.
700
+ */
693
701
  function ThemeProvider({ theme, children }) {
694
702
  provide(ThemeContext, theme);
695
703
  return children ?? null;
@@ -790,13 +798,48 @@ const createStyledComponent = (tag, strings, values, options) => {
790
798
  }
791
799
  const DynamicStyled = (rawProps) => {
792
800
  const theme = useTheme();
801
+ const $rs = rawProps.$rocketstyle;
802
+ const isReactiveRS = typeof $rs === "function";
803
+ const resolvedRS = isReactiveRS ? $rs() : $rs;
793
804
  const cssText = normalizeCSS(resolve(strings, values, {
794
- ...rawProps,
805
+ ...isReactiveRS ? {
806
+ ...rawProps,
807
+ $rocketstyle: resolvedRS
808
+ } : rawProps,
795
809
  theme
796
810
  }));
797
- const className = cssText.length > 0 ? sheet.insert(cssText, boost) : "";
811
+ const initialClassName = cssText.length > 0 ? sheet.insert(cssText, boost) : "";
798
812
  const finalTag = rawProps.as || tag;
799
- return h(finalTag, buildProps(rawProps, className, typeof finalTag === "string", customFilter), ...Array.isArray(rawProps.children) ? rawProps.children : rawProps.children != null ? [rawProps.children] : []);
813
+ const isDOM = typeof finalTag === "string";
814
+ let el = null;
815
+ let currentClassName = initialClassName;
816
+ const originalRef = rawProps.ref;
817
+ const refCallback = (node) => {
818
+ el = node;
819
+ if (originalRef) {
820
+ if (typeof originalRef === "function") originalRef(node);
821
+ else if (originalRef && typeof originalRef === "object") originalRef.current = node;
822
+ }
823
+ };
824
+ const finalProps = buildProps({
825
+ ...rawProps,
826
+ ref: isReactiveRS ? refCallback : rawProps.ref
827
+ }, initialClassName, isDOM, customFilter);
828
+ if (isReactiveRS) effect(() => {
829
+ const newRS = $rs();
830
+ const newCss = normalizeCSS(resolve(strings, values, {
831
+ ...rawProps,
832
+ $rocketstyle: newRS,
833
+ theme
834
+ }));
835
+ const newClass = newCss.length > 0 ? sheet.insert(newCss, boost) : "";
836
+ if (el && newClass !== currentClassName) {
837
+ if (currentClassName) el.classList.remove(currentClassName);
838
+ if (newClass) el.classList.add(newClass);
839
+ currentClassName = newClass;
840
+ }
841
+ });
842
+ return h(finalTag, finalProps, ...Array.isArray(rawProps.children) ? rawProps.children : rawProps.children != null ? [rawProps.children] : []);
800
843
  };
801
844
  DynamicStyled.displayName = `styled(${getDisplayName(tag)})`;
802
845
  return DynamicStyled;
package/package.json CHANGED
@@ -1,24 +1,13 @@
1
1
  {
2
2
  "name": "@pyreon/styler",
3
- "version": "0.11.5",
3
+ "version": "0.11.6",
4
+ "description": "Lightweight CSS-in-JS engine for Pyreon",
5
+ "license": "MIT",
4
6
  "repository": {
5
7
  "type": "git",
6
8
  "url": "https://github.com/pyreon/pyreon",
7
9
  "directory": "packages/ui-system/styler"
8
10
  },
9
- "description": "Lightweight CSS-in-JS engine for Pyreon",
10
- "license": "MIT",
11
- "type": "module",
12
- "sideEffects": false,
13
- "exports": {
14
- ".": {
15
- "bun": "./src/index.ts",
16
- "import": "./lib/index.js",
17
- "types": "./lib/index.d.ts"
18
- }
19
- },
20
- "types": "./lib/index.d.ts",
21
- "main": "./lib/index.js",
22
11
  "files": [
23
12
  "lib",
24
13
  "!lib/**/*.map",
@@ -27,8 +16,16 @@
27
16
  "LICENSE",
28
17
  "src"
29
18
  ],
30
- "engines": {
31
- "node": ">= 22"
19
+ "type": "module",
20
+ "sideEffects": false,
21
+ "main": "./lib/index.js",
22
+ "types": "./lib/index.d.ts",
23
+ "exports": {
24
+ ".": {
25
+ "bun": "./src/index.ts",
26
+ "import": "./lib/index.js",
27
+ "types": "./lib/index.d.ts"
28
+ }
32
29
  },
33
30
  "publishConfig": {
34
31
  "access": "public"
@@ -37,18 +34,21 @@
37
34
  "prepublish": "bun run build",
38
35
  "build": "bun run vl_rolldown_build",
39
36
  "build:watch": "bun run vl_rolldown_build-watch",
40
- "lint": "biome check src/",
37
+ "lint": "oxlint .",
41
38
  "test": "vitest run",
42
39
  "test:coverage": "vitest run --coverage",
43
40
  "test:watch": "vitest",
44
41
  "typecheck": "tsc --noEmit"
45
42
  },
43
+ "devDependencies": {
44
+ "@pyreon/typescript": "^0.11.6",
45
+ "@vitus-labs/tools-rolldown": "^1.15.3"
46
+ },
46
47
  "peerDependencies": {
47
- "@pyreon/core": "^0.11.5",
48
- "@pyreon/reactivity": "^0.11.5"
48
+ "@pyreon/core": "^0.11.6",
49
+ "@pyreon/reactivity": "^0.11.6"
49
50
  },
50
- "devDependencies": {
51
- "@vitus-labs/tools-rolldown": "^1.15.3",
52
- "@pyreon/typescript": "^0.11.5"
51
+ "engines": {
52
+ "node": ">= 22"
53
53
  }
54
54
  }
@@ -11,8 +11,8 @@
11
11
  * }
12
12
  * }
13
13
  */
14
- import type { VNode, VNodeChild } from "@pyreon/core"
15
- import { createContext, provide, useContext } from "@pyreon/core"
14
+ import type { VNode, VNodeChild } from '@pyreon/core'
15
+ import { createContext, provide, useContext } from '@pyreon/core'
16
16
 
17
17
  // biome-ignore lint/suspicious/noEmptyInterface: augmentable via module declaration merging
18
18
  export interface DefaultTheme {}
@@ -24,7 +24,14 @@ export const ThemeContext = createContext<Theme>({} as Theme)
24
24
  /** Hook to read the current theme from the nearest ThemeProvider. */
25
25
  export const useTheme = <T extends object = Theme>(): T => useContext(ThemeContext) as T
26
26
 
27
- /** Provides a theme object to all nested styled components via Pyreon context. */
27
+ /**
28
+ * @internal Low-level provider — use `PyreonUI` from `@pyreon/ui-core` instead.
29
+ *
30
+ * Provides a theme object to all nested styled components via Pyreon context.
31
+ *
32
+ * @deprecated Prefer `<PyreonUI theme={theme}>` which provides theme to
33
+ * all three context layers (styler, core, mode) in one component.
34
+ */
28
35
  export function ThemeProvider({
29
36
  theme,
30
37
  children,
@@ -1,19 +1,19 @@
1
- import { popContext } from "@pyreon/core"
2
- import { afterEach, describe, expect, it } from "vitest"
3
- import { ThemeContext, ThemeProvider, useTheme } from "../ThemeProvider"
1
+ import { popContext } from '@pyreon/core'
2
+ import { afterEach, describe, expect, it } from 'vitest'
3
+ import { ThemeContext, ThemeProvider, useTheme } from '../ThemeProvider'
4
4
 
5
- describe("ThemeContext", () => {
6
- it("is a Context object with an id", () => {
5
+ describe('ThemeContext', () => {
6
+ it('is a Context object with an id', () => {
7
7
  expect(ThemeContext).toBeDefined()
8
8
  expect(ThemeContext.id).toBeDefined()
9
9
  })
10
10
 
11
- it("has a symbol id for context identification", () => {
12
- expect(typeof ThemeContext.id).toBe("symbol")
11
+ it('has a symbol id for context identification', () => {
12
+ expect(typeof ThemeContext.id).toBe('symbol')
13
13
  })
14
14
  })
15
15
 
16
- describe("ThemeProvider", () => {
16
+ describe('ThemeProvider', () => {
17
17
  afterEach(() => {
18
18
  try {
19
19
  popContext()
@@ -22,41 +22,41 @@ describe("ThemeProvider", () => {
22
22
  }
23
23
  })
24
24
 
25
- it("returns children when provided", () => {
26
- const children = "Hello world"
25
+ it('returns children when provided', () => {
26
+ const children = 'Hello world'
27
27
  const result = ThemeProvider({ theme: {}, children })
28
- expect(result).toBe("Hello world")
28
+ expect(result).toBe('Hello world')
29
29
  })
30
30
 
31
- it("returns null when no children are provided", () => {
31
+ it('returns null when no children are provided', () => {
32
32
  const result = ThemeProvider({ theme: {} })
33
33
  expect(result).toBeNull()
34
34
  })
35
35
 
36
- it("returns null when children is undefined", () => {
36
+ it('returns null when children is undefined', () => {
37
37
  const result = ThemeProvider({ theme: {}, children: undefined })
38
38
  expect(result).toBeNull()
39
39
  })
40
40
 
41
- it("provides theme via context (useTheme returns it)", () => {
42
- const theme = { colors: { primary: "red" }, spacing: 8 }
43
- ThemeProvider({ theme, children: "child" })
41
+ it('provides theme via context (useTheme returns it)', () => {
42
+ const theme = { colors: { primary: 'red' }, spacing: 8 }
43
+ ThemeProvider({ theme, children: 'child' })
44
44
  const result = useTheme()
45
45
  expect(result).toEqual(theme)
46
46
  })
47
47
  })
48
48
 
49
- describe("useTheme", () => {
50
- it("is a function", () => {
51
- expect(typeof useTheme).toBe("function")
49
+ describe('useTheme', () => {
50
+ it('is a function', () => {
51
+ expect(typeof useTheme).toBe('function')
52
52
  })
53
53
 
54
- it("returns the default theme (empty object) when called outside a provider", () => {
54
+ it('returns the default theme (empty object) when called outside a provider', () => {
55
55
  const theme = useTheme()
56
56
  expect(theme).toEqual({})
57
57
  })
58
58
 
59
- it("can be called with a type parameter", () => {
59
+ it('can be called with a type parameter', () => {
60
60
  interface MyTheme {
61
61
  primary: string
62
62
  spacing: number
@@ -13,17 +13,17 @@
13
13
  * 7. styled() component factory
14
14
  * 8. normalizeCSS — Comment Stripping & Cleanup
15
15
  */
16
- import { bench, describe } from "vitest"
17
- import { css } from "../css"
18
- import { hash } from "../hash"
19
- import { normalizeCSS, resolve } from "../resolve"
20
- import { styled } from "../styled"
16
+ import { bench, describe } from 'vitest'
17
+ import { css } from '../css'
18
+ import { hash } from '../hash'
19
+ import { normalizeCSS, resolve } from '../resolve'
20
+ import { styled } from '../styled'
21
21
 
22
22
  // ============================================================================
23
23
  // 1. CSS Tagged Template — Creation Speed
24
24
  // ============================================================================
25
- describe("css() tagged template creation", () => {
26
- bench("@pyreon/styler", () => {
25
+ describe('css() tagged template creation', () => {
26
+ bench('@pyreon/styler', () => {
27
27
  css`
28
28
  display: flex;
29
29
  align-items: center;
@@ -32,7 +32,7 @@ describe("css() tagged template creation", () => {
32
32
  margin: 8px;
33
33
  background-color: #f0f0f0;
34
34
  border-radius: 4px;
35
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
35
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
36
36
  `
37
37
  })
38
38
  })
@@ -40,11 +40,11 @@ describe("css() tagged template creation", () => {
40
40
  // ============================================================================
41
41
  // 2. CSS Tagged Template with Interpolations
42
42
  // ============================================================================
43
- describe("css() with interpolations", () => {
44
- const color = "#ff0000"
45
- const size = "16px"
43
+ describe('css() with interpolations', () => {
44
+ const color = '#ff0000'
45
+ const size = '16px'
46
46
 
47
- bench("@pyreon/styler", () => {
47
+ bench('@pyreon/styler', () => {
48
48
  css`
49
49
  color: ${color};
50
50
  font-size: ${size};
@@ -57,15 +57,15 @@ describe("css() with interpolations", () => {
57
57
  // ============================================================================
58
58
  // 3. Template Resolution (strings + values -> CSS string)
59
59
  // ============================================================================
60
- describe("template resolution to CSS string", () => {
61
- const strings = Object.assign(["display: flex; color: ", "; font-size: ", "; padding: 8px;"], {
62
- raw: ["display: flex; color: ", "; font-size: ", "; padding: 8px;"],
60
+ describe('template resolution to CSS string', () => {
61
+ const strings = Object.assign(['display: flex; color: ', '; font-size: ', '; padding: 8px;'], {
62
+ raw: ['display: flex; color: ', '; font-size: ', '; padding: 8px;'],
63
63
  }) as unknown as TemplateStringsArray
64
64
 
65
- const values = ["red", "16px"]
66
- const props = { theme: { primary: "blue" } }
65
+ const values = ['red', '16px']
66
+ const props = { theme: { primary: 'blue' } }
67
67
 
68
- bench("@pyreon/styler resolve()", () => {
68
+ bench('@pyreon/styler resolve()', () => {
69
69
  resolve(strings, values, props)
70
70
  })
71
71
  })
@@ -73,20 +73,20 @@ describe("template resolution to CSS string", () => {
73
73
  // ============================================================================
74
74
  // 4. Dynamic Interpolation (function interpolations)
75
75
  // ============================================================================
76
- describe("dynamic function interpolation", () => {
77
- const props = { theme: { primary: "blue", size: "14px" }, active: true }
76
+ describe('dynamic function interpolation', () => {
77
+ const props = { theme: { primary: 'blue', size: '14px' }, active: true }
78
78
 
79
- const strings = Object.assign(["color: ", "; font-size: ", "; opacity: ", ";"], {
80
- raw: ["color: ", "; font-size: ", "; opacity: ", ";"],
79
+ const strings = Object.assign(['color: ', '; font-size: ', '; opacity: ', ';'], {
80
+ raw: ['color: ', '; font-size: ', '; opacity: ', ';'],
81
81
  }) as unknown as TemplateStringsArray
82
82
 
83
83
  const stylerValues = [
84
84
  (p: any) => p.theme.primary,
85
85
  (p: any) => p.theme.size,
86
- (p: any) => (p.active ? "1" : "0.5"),
86
+ (p: any) => (p.active ? '1' : '0.5'),
87
87
  ]
88
88
 
89
- bench("@pyreon/styler resolve()", () => {
89
+ bench('@pyreon/styler resolve()', () => {
90
90
  resolve(strings, stylerValues, props)
91
91
  })
92
92
  })
@@ -94,21 +94,21 @@ describe("dynamic function interpolation", () => {
94
94
  // ============================================================================
95
95
  // 5. Hash Function Throughput
96
96
  // ============================================================================
97
- describe("hash function throughput", () => {
98
- const shortCSS = "display: flex; color: red;"
97
+ describe('hash function throughput', () => {
98
+ const shortCSS = 'display: flex; color: red;'
99
99
  const mediumCSS =
100
- "display: flex; align-items: center; justify-content: space-between; padding: 16px 24px; margin: 0 auto; max-width: 1200px; background-color: #ffffff; border: 1px solid #e0e0e0; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.12);"
100
+ 'display: flex; align-items: center; justify-content: space-between; padding: 16px 24px; margin: 0 auto; max-width: 1200px; background-color: #ffffff; border: 1px solid #e0e0e0; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.12);'
101
101
  const longCSS = mediumCSS.repeat(5)
102
102
 
103
- bench("@pyreon/styler FNV-1a (short)", () => {
103
+ bench('@pyreon/styler FNV-1a (short)', () => {
104
104
  hash(shortCSS)
105
105
  })
106
106
 
107
- bench("@pyreon/styler FNV-1a (medium)", () => {
107
+ bench('@pyreon/styler FNV-1a (medium)', () => {
108
108
  hash(mediumCSS)
109
109
  })
110
110
 
111
- bench("@pyreon/styler FNV-1a (long)", () => {
111
+ bench('@pyreon/styler FNV-1a (long)', () => {
112
112
  hash(longCSS)
113
113
  })
114
114
  })
@@ -116,13 +116,20 @@ describe("hash function throughput", () => {
116
116
  // ============================================================================
117
117
  // 6. Nested css() Composition
118
118
  // ============================================================================
119
- describe("nested css() composition", () => {
120
- bench("@pyreon/styler", () => {
121
- const base = css`display: flex; padding: 8px;`
122
- const hover = css`background: #eee;`
119
+ describe('nested css() composition', () => {
120
+ bench('@pyreon/styler', () => {
121
+ const base = css`
122
+ display: flex;
123
+ padding: 8px;
124
+ `
125
+ const hover = css`
126
+ background: #eee;
127
+ `
123
128
  const result = css`
124
129
  ${base};
125
- &:hover { ${hover}; }
130
+ &:hover {
131
+ ${hover};
132
+ }
126
133
  color: red;
127
134
  `
128
135
  result.toString()
@@ -132,18 +139,22 @@ describe("nested css() composition", () => {
132
139
  // ============================================================================
133
140
  // 7. Styled Component Creation (factory call)
134
141
  // ============================================================================
135
- describe("styled() component factory", () => {
136
- bench("@pyreon/styler", () => {
137
- styled("div")`display: flex; color: red; padding: 8px;`
142
+ describe('styled() component factory', () => {
143
+ bench('@pyreon/styler', () => {
144
+ styled('div')`
145
+ display: flex;
146
+ color: red;
147
+ padding: 8px;
148
+ `
138
149
  })
139
150
  })
140
151
 
141
152
  // ============================================================================
142
153
  // 8. normalizeCSS — Comment Stripping & Cleanup
143
154
  // ============================================================================
144
- describe("normalizeCSS", () => {
155
+ describe('normalizeCSS', () => {
145
156
  const plain =
146
- " display: flex; align-items: center; justify-content: center; padding: 16px; margin: 8px; background-color: #f0f0f0; border-radius: 4px; "
157
+ ' display: flex; align-items: center; justify-content: center; padding: 16px; margin: 8px; background-color: #f0f0f0; border-radius: 4px; '
147
158
 
148
159
  const withBlockComments = `
149
160
  /* -------------------------------------------------------- */
@@ -169,21 +180,21 @@ describe("normalizeCSS", () => {
169
180
  background: url(https://example.com/img.png);
170
181
  `
171
182
 
172
- const withSemicolonJunk = " ; display: flex;; ; color: red; ; font-size: 1rem;; ; "
183
+ const withSemicolonJunk = ' ; display: flex;; ; color: red; ; font-size: 1rem;; ; '
173
184
 
174
- bench("plain CSS (no comments)", () => {
185
+ bench('plain CSS (no comments)', () => {
175
186
  normalizeCSS(plain)
176
187
  })
177
188
 
178
- bench("CSS with /* */ block comments", () => {
189
+ bench('CSS with /* */ block comments', () => {
179
190
  normalizeCSS(withBlockComments)
180
191
  })
181
192
 
182
- bench("CSS with // line comments", () => {
193
+ bench('CSS with // line comments', () => {
183
194
  normalizeCSS(withLineComments)
184
195
  })
185
196
 
186
- bench("CSS with semicolon junk", () => {
197
+ bench('CSS with semicolon junk', () => {
187
198
  normalizeCSS(withSemicolonJunk)
188
199
  })
189
200
  })