@pyreon/connector-document 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.
package/lib/index.d.ts CHANGED
@@ -25,7 +25,7 @@ declare function parseBoxModel(value: string | number | undefined, rootSize?: nu
25
25
  /**
26
26
  * Parse a CSS font-weight value.
27
27
  */
28
- declare function parseFontWeight(value: string | number | undefined): "normal" | "bold" | number | undefined;
28
+ declare function parseFontWeight(value: string | number | undefined): 'normal' | 'bold' | number | undefined;
29
29
  /**
30
30
  * Parse a CSS line-height value to a unitless number.
31
31
  */
package/package.json CHANGED
@@ -1,24 +1,13 @@
1
1
  {
2
2
  "name": "@pyreon/connector-document",
3
- "version": "0.11.5",
3
+ "version": "0.11.6",
4
+ "description": "Bridge between @pyreon/pyreon styled components and @pyreon/document rendering",
5
+ "license": "MIT",
4
6
  "repository": {
5
7
  "type": "git",
6
8
  "url": "https://github.com/pyreon/pyreon",
7
9
  "directory": "packages/ui-system/connector-document"
8
10
  },
9
- "description": "Bridge between @pyreon/pyreon styled components and @pyreon/document rendering",
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,20 +34,23 @@
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/core": "^0.11.6",
45
+ "@pyreon/document": "^0.11.6",
46
+ "@pyreon/typescript": "^0.11.6",
47
+ "@vitus-labs/tools-rolldown": "^1.15.4"
48
+ },
46
49
  "peerDependencies": {
47
- "@pyreon/core": "^0.11.5",
48
- "@pyreon/document": "^0.11.5"
50
+ "@pyreon/core": "^0.11.6",
51
+ "@pyreon/document": "^0.11.6"
49
52
  },
50
- "devDependencies": {
51
- "@pyreon/core": "^0.11.5",
52
- "@pyreon/document": "^0.11.5",
53
- "@vitus-labs/tools-rolldown": "^1.15.4",
54
- "@pyreon/typescript": "^0.11.5"
53
+ "engines": {
54
+ "node": ">= 22"
55
55
  }
56
56
  }
@@ -1,136 +1,136 @@
1
- import { describe, expect, it } from "vitest"
1
+ import { describe, expect, it } from 'vitest'
2
2
  import {
3
3
  parseBoxModel,
4
4
  parseCssDimension,
5
5
  parseFontWeight,
6
6
  parseLineHeight,
7
- } from "../cssValueParser"
7
+ } from '../cssValueParser'
8
8
 
9
- describe("parseCssDimension", () => {
10
- it("passes through numbers", () => {
9
+ describe('parseCssDimension', () => {
10
+ it('passes through numbers', () => {
11
11
  expect(parseCssDimension(14)).toBe(14)
12
12
  expect(parseCssDimension(0)).toBe(0)
13
13
  expect(parseCssDimension(-5)).toBe(-5)
14
14
  expect(parseCssDimension(1.5)).toBe(1.5)
15
15
  })
16
16
 
17
- it("parses px values", () => {
18
- expect(parseCssDimension("14px")).toBe(14)
19
- expect(parseCssDimension("0px")).toBe(0)
20
- expect(parseCssDimension("-5px")).toBe(-5)
21
- expect(parseCssDimension("1.5px")).toBe(1.5)
17
+ it('parses px values', () => {
18
+ expect(parseCssDimension('14px')).toBe(14)
19
+ expect(parseCssDimension('0px')).toBe(0)
20
+ expect(parseCssDimension('-5px')).toBe(-5)
21
+ expect(parseCssDimension('1.5px')).toBe(1.5)
22
22
  })
23
23
 
24
- it("parses rem values", () => {
25
- expect(parseCssDimension("1rem")).toBe(16)
26
- expect(parseCssDimension("1.5rem")).toBe(24)
27
- expect(parseCssDimension("0.5rem")).toBe(8)
28
- expect(parseCssDimension("2rem", 20)).toBe(40)
24
+ it('parses rem values', () => {
25
+ expect(parseCssDimension('1rem')).toBe(16)
26
+ expect(parseCssDimension('1.5rem')).toBe(24)
27
+ expect(parseCssDimension('0.5rem')).toBe(8)
28
+ expect(parseCssDimension('2rem', 20)).toBe(40)
29
29
  })
30
30
 
31
- it("parses em values", () => {
32
- expect(parseCssDimension("1em")).toBe(16)
33
- expect(parseCssDimension("2em")).toBe(32)
31
+ it('parses em values', () => {
32
+ expect(parseCssDimension('1em')).toBe(16)
33
+ expect(parseCssDimension('2em')).toBe(32)
34
34
  })
35
35
 
36
- it("parses pt values", () => {
37
- expect(parseCssDimension("12pt")).toBeCloseTo(16)
38
- expect(parseCssDimension("9pt")).toBeCloseTo(12)
36
+ it('parses pt values', () => {
37
+ expect(parseCssDimension('12pt')).toBeCloseTo(16)
38
+ expect(parseCssDimension('9pt')).toBeCloseTo(12)
39
39
  })
40
40
 
41
- it("parses bare number strings", () => {
42
- expect(parseCssDimension("14")).toBe(14)
43
- expect(parseCssDimension("0")).toBe(0)
44
- expect(parseCssDimension("-5")).toBe(-5)
41
+ it('parses bare number strings', () => {
42
+ expect(parseCssDimension('14')).toBe(14)
43
+ expect(parseCssDimension('0')).toBe(0)
44
+ expect(parseCssDimension('-5')).toBe(-5)
45
45
  })
46
46
 
47
- it("returns undefined for unresolvable values", () => {
48
- expect(parseCssDimension("auto")).toBeUndefined()
49
- expect(parseCssDimension("100%")).toBeUndefined()
50
- expect(parseCssDimension("calc(100% - 20px)")).toBeUndefined()
51
- expect(parseCssDimension("var(--spacing)")).toBeUndefined()
47
+ it('returns undefined for unresolvable values', () => {
48
+ expect(parseCssDimension('auto')).toBeUndefined()
49
+ expect(parseCssDimension('100%')).toBeUndefined()
50
+ expect(parseCssDimension('calc(100% - 20px)')).toBeUndefined()
51
+ expect(parseCssDimension('var(--spacing)')).toBeUndefined()
52
52
  })
53
53
 
54
- it("trims whitespace", () => {
55
- expect(parseCssDimension(" 14px ")).toBe(14)
56
- expect(parseCssDimension(" 1rem ")).toBe(16)
54
+ it('trims whitespace', () => {
55
+ expect(parseCssDimension(' 14px ')).toBe(14)
56
+ expect(parseCssDimension(' 1rem ')).toBe(16)
57
57
  })
58
58
  })
59
59
 
60
- describe("parseBoxModel", () => {
61
- it("returns undefined for null/undefined", () => {
60
+ describe('parseBoxModel', () => {
61
+ it('returns undefined for null/undefined', () => {
62
62
  expect(parseBoxModel(undefined)).toBeUndefined()
63
63
  expect(parseBoxModel(null as any)).toBeUndefined()
64
64
  })
65
65
 
66
- it("passes through numbers", () => {
66
+ it('passes through numbers', () => {
67
67
  expect(parseBoxModel(8)).toBe(8)
68
68
  expect(parseBoxModel(0)).toBe(0)
69
69
  })
70
70
 
71
- it("parses single value", () => {
72
- expect(parseBoxModel("8px")).toBe(8)
73
- expect(parseBoxModel("1rem")).toBe(16)
71
+ it('parses single value', () => {
72
+ expect(parseBoxModel('8px')).toBe(8)
73
+ expect(parseBoxModel('1rem')).toBe(16)
74
74
  })
75
75
 
76
- it("parses two values (vertical horizontal)", () => {
77
- expect(parseBoxModel("8px 16px")).toEqual([8, 16])
76
+ it('parses two values (vertical horizontal)', () => {
77
+ expect(parseBoxModel('8px 16px')).toEqual([8, 16])
78
78
  })
79
79
 
80
- it("parses three values (top horizontal bottom)", () => {
81
- expect(parseBoxModel("8px 16px 12px")).toEqual([8, 16, 12, 16])
80
+ it('parses three values (top horizontal bottom)', () => {
81
+ expect(parseBoxModel('8px 16px 12px')).toEqual([8, 16, 12, 16])
82
82
  })
83
83
 
84
- it("parses four values", () => {
85
- expect(parseBoxModel("8px 16px 12px 4px")).toEqual([8, 16, 12, 4])
84
+ it('parses four values', () => {
85
+ expect(parseBoxModel('8px 16px 12px 4px')).toEqual([8, 16, 12, 4])
86
86
  })
87
87
 
88
- it("returns undefined when any part is unresolvable", () => {
89
- expect(parseBoxModel("8px auto")).toBeUndefined()
90
- expect(parseBoxModel("8px 16px auto 4px")).toBeUndefined()
88
+ it('returns undefined when any part is unresolvable', () => {
89
+ expect(parseBoxModel('8px auto')).toBeUndefined()
90
+ expect(parseBoxModel('8px 16px auto 4px')).toBeUndefined()
91
91
  })
92
92
  })
93
93
 
94
- describe("parseFontWeight", () => {
95
- it("passes through numbers", () => {
94
+ describe('parseFontWeight', () => {
95
+ it('passes through numbers', () => {
96
96
  expect(parseFontWeight(400)).toBe(400)
97
97
  expect(parseFontWeight(700)).toBe(700)
98
98
  })
99
99
 
100
- it("handles string keywords", () => {
101
- expect(parseFontWeight("normal")).toBe("normal")
102
- expect(parseFontWeight("bold")).toBe("bold")
100
+ it('handles string keywords', () => {
101
+ expect(parseFontWeight('normal')).toBe('normal')
102
+ expect(parseFontWeight('bold')).toBe('bold')
103
103
  })
104
104
 
105
- it("parses numeric strings", () => {
106
- expect(parseFontWeight("400")).toBe(400)
107
- expect(parseFontWeight("700")).toBe(700)
105
+ it('parses numeric strings', () => {
106
+ expect(parseFontWeight('400')).toBe(400)
107
+ expect(parseFontWeight('700')).toBe(700)
108
108
  })
109
109
 
110
- it("returns undefined for null/undefined", () => {
110
+ it('returns undefined for null/undefined', () => {
111
111
  expect(parseFontWeight(undefined)).toBeUndefined()
112
112
  })
113
113
 
114
- it("returns undefined for unrecognized values", () => {
115
- expect(parseFontWeight("lighter")).toBeUndefined()
114
+ it('returns undefined for unrecognized values', () => {
115
+ expect(parseFontWeight('lighter')).toBeUndefined()
116
116
  })
117
117
  })
118
118
 
119
- describe("parseLineHeight", () => {
120
- it("passes through numbers (unitless)", () => {
119
+ describe('parseLineHeight', () => {
120
+ it('passes through numbers (unitless)', () => {
121
121
  expect(parseLineHeight(1.5)).toBe(1.5)
122
122
  expect(parseLineHeight(2)).toBe(2)
123
123
  })
124
124
 
125
- it("parses px values", () => {
126
- expect(parseLineHeight("24px")).toBe(24)
125
+ it('parses px values', () => {
126
+ expect(parseLineHeight('24px')).toBe(24)
127
127
  })
128
128
 
129
129
  it("returns undefined for 'normal'", () => {
130
- expect(parseLineHeight("normal")).toBeUndefined()
130
+ expect(parseLineHeight('normal')).toBeUndefined()
131
131
  })
132
132
 
133
- it("returns undefined for null/undefined", () => {
133
+ it('returns undefined for null/undefined', () => {
134
134
  expect(parseLineHeight(undefined)).toBeUndefined()
135
135
  })
136
136
  })
@@ -1,6 +1,6 @@
1
- import { describe, expect, it } from "vitest"
2
- import type { DocumentMarker } from "../extractDocumentTree"
3
- import { extractDocumentTree } from "../extractDocumentTree"
1
+ import { describe, expect, it } from 'vitest'
2
+ import type { DocumentMarker } from '../extractDocumentTree'
3
+ import { extractDocumentTree } from '../extractDocumentTree'
4
4
 
5
5
  // Helper: create a mock VNode
6
6
  const vnode = (
@@ -11,143 +11,143 @@ const vnode = (
11
11
 
12
12
  // Helper: create a document-marked component function
13
13
  const docComponent = (docType: string, render?: (...args: any[]) => any) => {
14
- const fn = render ?? ((props: any) => vnode("div", props, props.children ? [props.children] : []))
14
+ const fn = render ?? ((props: any) => vnode('div', props, props.children ? [props.children] : []))
15
15
  ;(fn as any)._documentType = docType
16
16
  return fn as ((...args: any[]) => any) & DocumentMarker
17
17
  }
18
18
 
19
- describe("extractDocumentTree", () => {
20
- it("extracts a simple document node", () => {
21
- const Heading = docComponent("heading")
19
+ describe('extractDocumentTree', () => {
20
+ it('extracts a simple document node', () => {
21
+ const Heading = docComponent('heading')
22
22
  const tree = vnode(
23
23
  Heading,
24
- { $rocketstyle: { fontSize: 24, fontWeight: "bold" }, _documentProps: { level: 1 } },
25
- ["Hello World"],
24
+ { $rocketstyle: { fontSize: 24, fontWeight: 'bold' }, _documentProps: { level: 1 } },
25
+ ['Hello World'],
26
26
  )
27
27
 
28
28
  const result = extractDocumentTree(tree)
29
29
 
30
- expect(result.type).toBe("heading")
30
+ expect(result.type).toBe('heading')
31
31
  expect(result.props).toEqual({ level: 1 })
32
- expect(result.children).toEqual(["Hello World"])
33
- expect(result.styles).toEqual({ fontSize: 24, fontWeight: "bold" })
32
+ expect(result.children).toEqual(['Hello World'])
33
+ expect(result.styles).toEqual({ fontSize: 24, fontWeight: 'bold' })
34
34
  })
35
35
 
36
- it("extracts nested document nodes", () => {
37
- const Section = docComponent("section")
38
- const Text = docComponent("text")
36
+ it('extracts nested document nodes', () => {
37
+ const Section = docComponent('section')
38
+ const Text = docComponent('text')
39
39
 
40
40
  const tree = vnode(Section, { $rocketstyle: { padding: 16 } }, [
41
- vnode(Text, { $rocketstyle: { fontSize: 14, color: "#333" } }, ["Paragraph one"]),
42
- vnode(Text, { $rocketstyle: { fontSize: 14, color: "#333" } }, ["Paragraph two"]),
41
+ vnode(Text, { $rocketstyle: { fontSize: 14, color: '#333' } }, ['Paragraph one']),
42
+ vnode(Text, { $rocketstyle: { fontSize: 14, color: '#333' } }, ['Paragraph two']),
43
43
  ])
44
44
 
45
45
  const result = extractDocumentTree(tree)
46
46
 
47
- expect(result.type).toBe("section")
47
+ expect(result.type).toBe('section')
48
48
  expect(result.styles).toEqual({ padding: 16 })
49
49
  expect(result.children).toHaveLength(2)
50
- expect((result.children[0] as any).type).toBe("text")
51
- expect((result.children[1] as any).type).toBe("text")
50
+ expect((result.children[0] as any).type).toBe('text')
51
+ expect((result.children[1] as any).type).toBe('text')
52
52
  })
53
53
 
54
- it("flattens transparent wrappers", () => {
55
- const Section = docComponent("section")
56
- const Text = docComponent("text")
54
+ it('flattens transparent wrappers', () => {
55
+ const Section = docComponent('section')
56
+ const Text = docComponent('text')
57
57
 
58
58
  // A plain div wrapper (no _documentType) should be transparent
59
59
  const tree = vnode(Section, {}, [
60
- vnode("div", {}, [vnode(Text, { $rocketstyle: { fontSize: 14 } }, ["Hello"])]),
60
+ vnode('div', {}, [vnode(Text, { $rocketstyle: { fontSize: 14 } }, ['Hello'])]),
61
61
  ])
62
62
 
63
63
  const result = extractDocumentTree(tree)
64
64
 
65
- expect(result.type).toBe("section")
65
+ expect(result.type).toBe('section')
66
66
  expect(result.children).toHaveLength(1)
67
- expect((result.children[0] as any).type).toBe("text")
67
+ expect((result.children[0] as any).type).toBe('text')
68
68
  })
69
69
 
70
- it("handles string children", () => {
71
- const Text = docComponent("text")
72
- const tree = vnode(Text, {}, ["Hello", " ", "World"])
70
+ it('handles string children', () => {
71
+ const Text = docComponent('text')
72
+ const tree = vnode(Text, {}, ['Hello', ' ', 'World'])
73
73
 
74
74
  const result = extractDocumentTree(tree)
75
75
 
76
- expect(result.children).toEqual(["Hello", " ", "World"])
76
+ expect(result.children).toEqual(['Hello', ' ', 'World'])
77
77
  })
78
78
 
79
- it("handles number children", () => {
80
- const Text = docComponent("text")
79
+ it('handles number children', () => {
80
+ const Text = docComponent('text')
81
81
  const tree = vnode(Text, {}, [42])
82
82
 
83
83
  const result = extractDocumentTree(tree)
84
84
 
85
- expect(result.children).toEqual(["42"])
85
+ expect(result.children).toEqual(['42'])
86
86
  })
87
87
 
88
- it("skips null and boolean children", () => {
89
- const Section = docComponent("section")
90
- const tree = vnode(Section, {}, [null, false, true, "visible"])
88
+ it('skips null and boolean children', () => {
89
+ const Section = docComponent('section')
90
+ const tree = vnode(Section, {}, [null, false, true, 'visible'])
91
91
 
92
92
  const result = extractDocumentTree(tree)
93
93
 
94
- expect(result.children).toEqual(["visible"])
94
+ expect(result.children).toEqual(['visible'])
95
95
  })
96
96
 
97
- it("resolves reactive getter children", () => {
98
- const Text = docComponent("text")
99
- const tree = vnode(Text, {}, [() => "dynamic text"])
97
+ it('resolves reactive getter children', () => {
98
+ const Text = docComponent('text')
99
+ const tree = vnode(Text, {}, [() => 'dynamic text'])
100
100
 
101
101
  const result = extractDocumentTree(tree)
102
102
 
103
- expect(result.children).toEqual(["dynamic text"])
103
+ expect(result.children).toEqual(['dynamic text'])
104
104
  })
105
105
 
106
- it("omits styles when includeStyles is false", () => {
107
- const Heading = docComponent("heading")
108
- const tree = vnode(Heading, { $rocketstyle: { fontSize: 24 } }, ["Hello"])
106
+ it('omits styles when includeStyles is false', () => {
107
+ const Heading = docComponent('heading')
108
+ const tree = vnode(Heading, { $rocketstyle: { fontSize: 24 } }, ['Hello'])
109
109
 
110
110
  const result = extractDocumentTree(tree, { includeStyles: false })
111
111
 
112
112
  expect(result.styles).toBeUndefined()
113
113
  })
114
114
 
115
- it("wraps in document node when root has no _documentType", () => {
116
- const tree = vnode("div", {}, ["raw text"])
115
+ it('wraps in document node when root has no _documentType', () => {
116
+ const tree = vnode('div', {}, ['raw text'])
117
117
 
118
118
  const result = extractDocumentTree(tree)
119
119
 
120
- expect(result.type).toBe("document")
121
- expect(result.children).toEqual(["raw text"])
120
+ expect(result.type).toBe('document')
121
+ expect(result.children).toEqual(['raw text'])
122
122
  })
123
123
 
124
- it("handles component functions without _documentType by calling them", () => {
125
- const Text = docComponent("text")
124
+ it('handles component functions without _documentType by calling them', () => {
125
+ const Text = docComponent('text')
126
126
  const Wrapper = (props: any) =>
127
127
  vnode(Text, { $rocketstyle: { fontSize: 14 } }, [props.children])
128
128
 
129
- const tree = vnode(Wrapper, {}, ["wrapped text"])
129
+ const tree = vnode(Wrapper, {}, ['wrapped text'])
130
130
 
131
131
  const result = extractDocumentTree(tree)
132
132
 
133
- expect(result.type).toBe("text")
134
- expect(result.children).toEqual(["wrapped text"])
133
+ expect(result.type).toBe('text')
134
+ expect(result.children).toEqual(['wrapped text'])
135
135
  })
136
136
 
137
- it("handles function passed directly", () => {
138
- const Text = docComponent("text")
139
- const template = () => vnode(Text, { $rocketstyle: { fontSize: 14 } }, ["Hello"])
137
+ it('handles function passed directly', () => {
138
+ const Text = docComponent('text')
139
+ const template = () => vnode(Text, { $rocketstyle: { fontSize: 14 } }, ['Hello'])
140
140
 
141
141
  const result = extractDocumentTree(template)
142
142
 
143
- expect(result.type).toBe("text")
144
- expect(result.children).toEqual(["Hello"])
143
+ expect(result.type).toBe('text')
144
+ expect(result.children).toEqual(['Hello'])
145
145
  })
146
146
 
147
- it("creates empty document for null input", () => {
147
+ it('creates empty document for null input', () => {
148
148
  const result = extractDocumentTree(null)
149
149
 
150
- expect(result.type).toBe("document")
150
+ expect(result.type).toBe('document')
151
151
  expect(result.children).toEqual([])
152
152
  })
153
153
  })
@@ -1,37 +1,37 @@
1
- import { describe, expect, it } from "vitest"
2
- import { resolveStyles } from "../resolveStyles"
1
+ import { describe, expect, it } from 'vitest'
2
+ import { resolveStyles } from '../resolveStyles'
3
3
 
4
- describe("resolveStyles", () => {
5
- it("resolves typography properties", () => {
4
+ describe('resolveStyles', () => {
5
+ it('resolves typography properties', () => {
6
6
  const result = resolveStyles({
7
- fontSize: "14px",
8
- fontFamily: "system-ui, sans-serif",
9
- fontWeight: "bold",
10
- fontStyle: "italic",
11
- textDecoration: "underline",
12
- color: "#333333",
13
- textAlign: "center",
7
+ fontSize: '14px',
8
+ fontFamily: 'system-ui, sans-serif',
9
+ fontWeight: 'bold',
10
+ fontStyle: 'italic',
11
+ textDecoration: 'underline',
12
+ color: '#333333',
13
+ textAlign: 'center',
14
14
  lineHeight: 1.5,
15
- letterSpacing: "0.5px",
15
+ letterSpacing: '0.5px',
16
16
  })
17
17
 
18
18
  expect(result).toEqual({
19
19
  fontSize: 14,
20
- fontFamily: "system-ui, sans-serif",
21
- fontWeight: "bold",
22
- fontStyle: "italic",
23
- textDecoration: "underline",
24
- color: "#333333",
25
- textAlign: "center",
20
+ fontFamily: 'system-ui, sans-serif',
21
+ fontWeight: 'bold',
22
+ fontStyle: 'italic',
23
+ textDecoration: 'underline',
24
+ color: '#333333',
25
+ textAlign: 'center',
26
26
  lineHeight: 1.5,
27
27
  letterSpacing: 0.5,
28
28
  })
29
29
  })
30
30
 
31
- it("resolves box model properties", () => {
31
+ it('resolves box model properties', () => {
32
32
  const result = resolveStyles({
33
- padding: "8px 16px",
34
- margin: "12px",
33
+ padding: '8px 16px',
34
+ margin: '12px',
35
35
  })
36
36
 
37
37
  expect(result).toEqual({
@@ -40,37 +40,37 @@ describe("resolveStyles", () => {
40
40
  })
41
41
  })
42
42
 
43
- it("resolves border properties", () => {
43
+ it('resolves border properties', () => {
44
44
  const result = resolveStyles({
45
- borderRadius: "4px",
46
- borderWidth: "1px",
47
- borderColor: "#dddddd",
48
- borderStyle: "solid",
45
+ borderRadius: '4px',
46
+ borderWidth: '1px',
47
+ borderColor: '#dddddd',
48
+ borderStyle: 'solid',
49
49
  })
50
50
 
51
51
  expect(result).toEqual({
52
52
  borderRadius: 4,
53
53
  borderWidth: 1,
54
- borderColor: "#dddddd",
55
- borderStyle: "solid",
54
+ borderColor: '#dddddd',
55
+ borderStyle: 'solid',
56
56
  })
57
57
  })
58
58
 
59
- it("resolves sizing properties", () => {
59
+ it('resolves sizing properties', () => {
60
60
  const result = resolveStyles({
61
- width: "200px",
61
+ width: '200px',
62
62
  height: 100,
63
- maxWidth: "100%",
63
+ maxWidth: '100%',
64
64
  })
65
65
 
66
66
  expect(result).toEqual({
67
67
  width: 200,
68
68
  height: 100,
69
- maxWidth: "100%",
69
+ maxWidth: '100%',
70
70
  })
71
71
  })
72
72
 
73
- it("handles numeric values directly", () => {
73
+ it('handles numeric values directly', () => {
74
74
  const result = resolveStyles({
75
75
  fontSize: 14,
76
76
  padding: 8,
@@ -84,41 +84,41 @@ describe("resolveStyles", () => {
84
84
  })
85
85
  })
86
86
 
87
- it("ignores irrelevant CSS properties", () => {
87
+ it('ignores irrelevant CSS properties', () => {
88
88
  const result = resolveStyles({
89
89
  fontSize: 14,
90
- transition: "all 0.2s",
91
- cursor: "pointer",
92
- display: "flex",
93
- position: "relative",
94
- transform: "translateX(10px)",
90
+ transition: 'all 0.2s',
91
+ cursor: 'pointer',
92
+ display: 'flex',
93
+ position: 'relative',
94
+ transform: 'translateX(10px)',
95
95
  })
96
96
 
97
97
  expect(result).toEqual({ fontSize: 14 })
98
98
  })
99
99
 
100
- it("skips invalid values", () => {
100
+ it('skips invalid values', () => {
101
101
  const result = resolveStyles({
102
- fontStyle: "oblique",
103
- textDecoration: "overline",
104
- borderStyle: "none",
105
- textAlign: "start",
102
+ fontStyle: 'oblique',
103
+ textDecoration: 'overline',
104
+ borderStyle: 'none',
105
+ textAlign: 'start',
106
106
  })
107
107
 
108
108
  expect(result).toEqual({})
109
109
  })
110
110
 
111
- it("returns empty object for empty input", () => {
111
+ it('returns empty object for empty input', () => {
112
112
  expect(resolveStyles({})).toEqual({})
113
113
  })
114
114
 
115
- it("handles backgroundColor", () => {
116
- const result = resolveStyles({ backgroundColor: "#4f46e5" })
117
- expect(result).toEqual({ backgroundColor: "#4f46e5" })
115
+ it('handles backgroundColor', () => {
116
+ const result = resolveStyles({ backgroundColor: '#4f46e5' })
117
+ expect(result).toEqual({ backgroundColor: '#4f46e5' })
118
118
  })
119
119
 
120
- it("converts rem values using rootSize", () => {
121
- const result = resolveStyles({ fontSize: "1.5rem" }, 20)
120
+ it('converts rem values using rootSize', () => {
121
+ const result = resolveStyles({ fontSize: '1.5rem' }, 20)
122
122
  expect(result).toEqual({ fontSize: 30 })
123
123
  })
124
124
  })
@@ -20,8 +20,8 @@ export function parseCssDimension(
20
20
  rootSize = DEFAULT_ROOT_SIZE,
21
21
  ): number | undefined {
22
22
  if (value == null) return undefined
23
- if (typeof value === "number") return value
24
- if (typeof value !== "string") return undefined
23
+ if (typeof value === 'number') return value
24
+ if (typeof value !== 'string') return undefined
25
25
 
26
26
  const trimmed = value.trim()
27
27
 
@@ -58,7 +58,7 @@ export function parseBoxModel(
58
58
  rootSize = DEFAULT_ROOT_SIZE,
59
59
  ): BoxModelResult {
60
60
  if (value == null) return undefined
61
- if (typeof value === "number") return value
61
+ if (typeof value === 'number') return value
62
62
 
63
63
  const parts = value
64
64
  .trim()
@@ -83,10 +83,10 @@ export function parseBoxModel(
83
83
  */
84
84
  export function parseFontWeight(
85
85
  value: string | number | undefined,
86
- ): "normal" | "bold" | number | undefined {
86
+ ): 'normal' | 'bold' | number | undefined {
87
87
  if (value == null) return undefined
88
- if (typeof value === "number") return value
89
- if (value === "normal" || value === "bold") return value
88
+ if (typeof value === 'number') return value
89
+ if (value === 'normal' || value === 'bold') return value
90
90
  const num = Number.parseInt(value, 10)
91
91
  if (!Number.isNaN(num)) return num
92
92
  return undefined
@@ -100,8 +100,8 @@ export function parseLineHeight(
100
100
  rootSize = DEFAULT_ROOT_SIZE,
101
101
  ): number | undefined {
102
102
  if (value == null) return undefined
103
- if (typeof value === "number") return value
104
- if (value === "normal") return undefined
103
+ if (typeof value === 'number') return value
104
+ if (value === 'normal') return undefined
105
105
 
106
106
  const dim = parseCssDimension(value, rootSize)
107
107
  if (dim != null) return dim
@@ -1,5 +1,5 @@
1
- import { resolveStyles } from "./resolveStyles"
2
- import type { DocChild, DocNode, NodeType } from "./types"
1
+ import { resolveStyles } from './resolveStyles'
2
+ import type { DocChild, DocNode, NodeType } from './types'
3
3
 
4
4
  /** Marker interface: components with _documentType are extractable. */
5
5
  export interface DocumentMarker {
@@ -20,15 +20,15 @@ type VNodeLike = {
20
20
  }
21
21
 
22
22
  function isVNode(value: unknown): value is VNodeLike {
23
- return value != null && typeof value === "object" && "type" in value && "props" in value
23
+ return value != null && typeof value === 'object' && 'type' in value && 'props' in value
24
24
  }
25
25
 
26
26
  function getDocumentType(fn: unknown): NodeType | undefined {
27
- if (typeof fn !== "function") return undefined
27
+ if (typeof fn !== 'function') return undefined
28
28
  const meta = (fn as any).meta
29
29
  if (meta?._documentType) return meta._documentType as NodeType
30
30
  // Fallback: check directly on function (non-rocketstyle components)
31
- if ("_documentType" in fn) return (fn as any)._documentType as NodeType
31
+ if ('_documentType' in fn) return (fn as any)._documentType as NodeType
32
32
  return undefined
33
33
  }
34
34
 
@@ -37,7 +37,7 @@ function flattenChildren(children: unknown[]): unknown[] {
37
37
  for (const child of children) {
38
38
  if (Array.isArray(child)) {
39
39
  result.push(...flattenChildren(child))
40
- } else if (typeof child === "function") {
40
+ } else if (typeof child === 'function') {
41
41
  // Reactive getter — call to resolve
42
42
  const resolved = child()
43
43
  if (Array.isArray(resolved)) {
@@ -59,12 +59,12 @@ function extractChildren(children: unknown[], options: ExtractOptions): DocChild
59
59
  for (const child of flat) {
60
60
  if (child == null || child === false || child === true) continue
61
61
 
62
- if (typeof child === "string") {
62
+ if (typeof child === 'string') {
63
63
  result.push(child)
64
64
  continue
65
65
  }
66
66
 
67
- if (typeof child === "number") {
67
+ if (typeof child === 'number') {
68
68
  result.push(String(child))
69
69
  continue
70
70
  }
@@ -93,7 +93,7 @@ function extractNode(vnode: VNodeLike, options: ExtractOptions): DocNode | DocCh
93
93
  const docProps: Record<string, unknown> = {}
94
94
 
95
95
  // Extract document-specific props from _documentProps
96
- if (props._documentProps && typeof props._documentProps === "object") {
96
+ if (props._documentProps && typeof props._documentProps === 'object') {
97
97
  Object.assign(docProps, props._documentProps)
98
98
  }
99
99
 
@@ -120,7 +120,7 @@ function extractNode(vnode: VNodeLike, options: ExtractOptions): DocNode | DocCh
120
120
  }
121
121
 
122
122
  // Component function WITHOUT _documentType — call it to get its VNode output
123
- if (typeof type === "function") {
123
+ if (typeof type === 'function') {
124
124
  const mergedProps = { ...props }
125
125
  if (children && children.length > 0) {
126
126
  mergedProps.children = children.length === 1 ? children[0] : children
@@ -133,13 +133,13 @@ function extractNode(vnode: VNodeLike, options: ExtractOptions): DocNode | DocCh
133
133
  }
134
134
 
135
135
  // The component returned a primitive or null
136
- if (typeof result === "string") return [result]
137
- if (typeof result === "number") return [String(result)]
136
+ if (typeof result === 'string') return [result]
137
+ if (typeof result === 'number') return [String(result)]
138
138
  return null
139
139
  }
140
140
 
141
141
  // DOM element (string type like 'div', 'span') — transparent, extract children
142
- if (typeof type === "string") {
142
+ if (typeof type === 'string') {
143
143
  const docChildren = extractChildren(children ?? [], options)
144
144
  // If there's text content in the DOM element, collect it
145
145
  if (docChildren.length > 0) return docChildren
@@ -168,14 +168,14 @@ export function extractDocumentTree(vnode: unknown, options: ExtractOptions = {}
168
168
 
169
169
  // Wrap loose children in a document node
170
170
  const children = Array.isArray(result) ? result : []
171
- return { type: "document", props: {}, children }
171
+ return { type: 'document', props: {}, children }
172
172
  }
173
173
 
174
174
  // If passed a component function directly, call it
175
- if (typeof vnode === "function") {
175
+ if (typeof vnode === 'function') {
176
176
  const result = (vnode as () => unknown)()
177
177
  return extractDocumentTree(result, options)
178
178
  }
179
179
 
180
- return { type: "document", props: {}, children: [] }
180
+ return { type: 'document', props: {}, children: [] }
181
181
  }
package/src/index.ts CHANGED
@@ -3,8 +3,8 @@ export {
3
3
  parseCssDimension,
4
4
  parseFontWeight,
5
5
  parseLineHeight,
6
- } from "./cssValueParser"
7
- export type { DocumentMarker, ExtractOptions } from "./extractDocumentTree"
8
- export { extractDocumentTree } from "./extractDocumentTree"
9
- export { resolveStyles } from "./resolveStyles"
10
- export type { DocChild, DocNode, NodeType, ResolvedStyles } from "./types"
6
+ } from './cssValueParser'
7
+ export type { DocumentMarker, ExtractOptions } from './extractDocumentTree'
8
+ export { extractDocumentTree } from './extractDocumentTree'
9
+ export { resolveStyles } from './resolveStyles'
10
+ export type { DocChild, DocNode, NodeType, ResolvedStyles } from './types'
@@ -3,13 +3,13 @@ import {
3
3
  parseCssDimension,
4
4
  parseFontWeight,
5
5
  parseLineHeight,
6
- } from "./cssValueParser"
7
- import type { ResolvedStyles } from "./types"
6
+ } from './cssValueParser'
7
+ import type { ResolvedStyles } from './types'
8
8
 
9
- const TEXT_ALIGN_VALUES = new Set(["left", "center", "right", "justify"])
10
- const FONT_STYLE_VALUES = new Set(["normal", "italic"])
11
- const TEXT_DECORATION_VALUES = new Set(["none", "underline", "line-through"])
12
- const BORDER_STYLE_VALUES = new Set(["solid", "dashed", "dotted"])
9
+ const TEXT_ALIGN_VALUES = new Set(['left', 'center', 'right', 'justify'])
10
+ const FONT_STYLE_VALUES = new Set(['normal', 'italic'])
11
+ const TEXT_DECORATION_VALUES = new Set(['none', 'underline', 'line-through'])
12
+ const BORDER_STYLE_VALUES = new Set(['solid', 'dashed', 'dotted'])
13
13
 
14
14
  /**
15
15
  * Convert a rocketstyle `$rocketstyle` theme object into a `ResolvedStyles`
@@ -25,27 +25,27 @@ export function resolveStyles(rocketstyle: Record<string, unknown>, rootSize = 1
25
25
  const fontSize = parseCssDimension(rocketstyle.fontSize as string | number, rootSize)
26
26
  if (fontSize != null) styles.fontSize = fontSize
27
27
 
28
- if (typeof rocketstyle.fontFamily === "string") styles.fontFamily = rocketstyle.fontFamily
28
+ if (typeof rocketstyle.fontFamily === 'string') styles.fontFamily = rocketstyle.fontFamily
29
29
 
30
30
  const fontWeight = parseFontWeight(rocketstyle.fontWeight as string | number | undefined)
31
31
  if (fontWeight != null) styles.fontWeight = fontWeight
32
32
 
33
- if (typeof rocketstyle.fontStyle === "string" && FONT_STYLE_VALUES.has(rocketstyle.fontStyle))
34
- styles.fontStyle = rocketstyle.fontStyle as "normal" | "italic"
33
+ if (typeof rocketstyle.fontStyle === 'string' && FONT_STYLE_VALUES.has(rocketstyle.fontStyle))
34
+ styles.fontStyle = rocketstyle.fontStyle as 'normal' | 'italic'
35
35
 
36
36
  if (
37
- typeof rocketstyle.textDecoration === "string" &&
37
+ typeof rocketstyle.textDecoration === 'string' &&
38
38
  TEXT_DECORATION_VALUES.has(rocketstyle.textDecoration)
39
39
  )
40
- styles.textDecoration = rocketstyle.textDecoration as "none" | "underline" | "line-through"
40
+ styles.textDecoration = rocketstyle.textDecoration as 'none' | 'underline' | 'line-through'
41
41
 
42
- if (typeof rocketstyle.color === "string") styles.color = rocketstyle.color
42
+ if (typeof rocketstyle.color === 'string') styles.color = rocketstyle.color
43
43
 
44
- if (typeof rocketstyle.backgroundColor === "string")
44
+ if (typeof rocketstyle.backgroundColor === 'string')
45
45
  styles.backgroundColor = rocketstyle.backgroundColor
46
46
 
47
- if (typeof rocketstyle.textAlign === "string" && TEXT_ALIGN_VALUES.has(rocketstyle.textAlign))
48
- styles.textAlign = rocketstyle.textAlign as "left" | "center" | "right" | "justify"
47
+ if (typeof rocketstyle.textAlign === 'string' && TEXT_ALIGN_VALUES.has(rocketstyle.textAlign))
48
+ styles.textAlign = rocketstyle.textAlign as 'left' | 'center' | 'right' | 'justify'
49
49
 
50
50
  const lineHeight = parseLineHeight(
51
51
  rocketstyle.lineHeight as string | number | undefined,
@@ -70,13 +70,13 @@ export function resolveStyles(rocketstyle: Record<string, unknown>, rootSize = 1
70
70
  const borderWidth = parseCssDimension(rocketstyle.borderWidth as string | number, rootSize)
71
71
  if (borderWidth != null) styles.borderWidth = borderWidth
72
72
 
73
- if (typeof rocketstyle.borderColor === "string") styles.borderColor = rocketstyle.borderColor
73
+ if (typeof rocketstyle.borderColor === 'string') styles.borderColor = rocketstyle.borderColor
74
74
 
75
75
  if (
76
- typeof rocketstyle.borderStyle === "string" &&
76
+ typeof rocketstyle.borderStyle === 'string' &&
77
77
  BORDER_STYLE_VALUES.has(rocketstyle.borderStyle)
78
78
  )
79
- styles.borderStyle = rocketstyle.borderStyle as "solid" | "dashed" | "dotted"
79
+ styles.borderStyle = rocketstyle.borderStyle as 'solid' | 'dashed' | 'dotted'
80
80
 
81
81
  // Sizing
82
82
  if (rocketstyle.width != null) {
@@ -95,7 +95,7 @@ export function resolveStyles(rocketstyle: Record<string, unknown>, rootSize = 1
95
95
  }
96
96
 
97
97
  // Opacity
98
- if (typeof rocketstyle.opacity === "number") styles.opacity = rocketstyle.opacity
98
+ if (typeof rocketstyle.opacity === 'number') styles.opacity = rocketstyle.opacity
99
99
 
100
100
  return styles
101
101
  }
package/src/types.ts CHANGED
@@ -1 +1 @@
1
- export type { DocChild, DocNode, NodeType, ResolvedStyles } from "@pyreon/document"
1
+ export type { DocChild, DocNode, NodeType, ResolvedStyles } from '@pyreon/document'