@pyreon/head 0.12.7 → 0.12.9
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/head",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.9",
|
|
4
4
|
"description": "Head tag management for Pyreon — works in SSR and CSR",
|
|
5
5
|
"homepage": "https://github.com/pyreon/pyreon/tree/main/packages/head#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -57,16 +57,16 @@
|
|
|
57
57
|
"prepublishOnly": "bun run build"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@pyreon/core": "^0.12.
|
|
61
|
-
"@pyreon/reactivity": "^0.12.
|
|
60
|
+
"@pyreon/core": "^0.12.9",
|
|
61
|
+
"@pyreon/reactivity": "^0.12.9"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@happy-dom/global-registrator": "^20.8.9",
|
|
65
|
-
"@pyreon/runtime-dom": "^0.12.
|
|
66
|
-
"@pyreon/runtime-server": "^0.12.
|
|
65
|
+
"@pyreon/runtime-dom": "^0.12.9",
|
|
66
|
+
"@pyreon/runtime-server": "^0.12.9"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@pyreon/runtime-server": "^0.12.
|
|
69
|
+
"@pyreon/runtime-server": "^0.12.9"
|
|
70
70
|
},
|
|
71
71
|
"peerDependenciesMeta": {
|
|
72
72
|
"@pyreon/runtime-server": {
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { h } from '@pyreon/core'
|
|
2
|
+
import { signal } from '@pyreon/reactivity'
|
|
3
|
+
import { mount } from '@pyreon/runtime-dom'
|
|
4
|
+
import type { HeadContextValue } from '../index'
|
|
5
|
+
import { createHeadContext, HeadProvider, useHead } from '../index'
|
|
6
|
+
|
|
7
|
+
// ─── Integration tests ───────────────────────────────────────────────────────
|
|
8
|
+
|
|
9
|
+
describe('Head integration — CSR', () => {
|
|
10
|
+
let container: HTMLElement
|
|
11
|
+
let ctx: HeadContextValue
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
container = document.createElement('div')
|
|
15
|
+
document.body.appendChild(container)
|
|
16
|
+
ctx = createHeadContext()
|
|
17
|
+
for (const el of document.head.querySelectorAll('[data-pyreon-head]')) el.remove()
|
|
18
|
+
document.title = ''
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
container.remove()
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('useHead({ title }) updates document.title', () => {
|
|
26
|
+
function Page() {
|
|
27
|
+
useHead({ title: 'Page' })
|
|
28
|
+
return h('div', null, 'content')
|
|
29
|
+
}
|
|
30
|
+
mount(h(HeadProvider, { context: ctx, children: h(Page, null) }), container)
|
|
31
|
+
expect(document.title).toBe('Page')
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('useHead({ meta }) injects meta tag into head', () => {
|
|
35
|
+
function Page() {
|
|
36
|
+
useHead({ meta: [{ name: 'description', content: 'Integration test' }] })
|
|
37
|
+
return h('div', null)
|
|
38
|
+
}
|
|
39
|
+
mount(h(HeadProvider, { context: ctx, children: h(Page, null) }), container)
|
|
40
|
+
const meta = document.head.querySelector('meta[name="description"]')
|
|
41
|
+
expect(meta).not.toBeNull()
|
|
42
|
+
expect(meta?.getAttribute('content')).toBe('Integration test')
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('reactive useHead updates title when signal changes', () => {
|
|
46
|
+
const title = signal('Initial')
|
|
47
|
+
function Page() {
|
|
48
|
+
useHead(() => ({ title: title() }))
|
|
49
|
+
return h('div', null)
|
|
50
|
+
}
|
|
51
|
+
mount(h(HeadProvider, { context: ctx, children: h(Page, null) }), container)
|
|
52
|
+
expect(document.title).toBe('Initial')
|
|
53
|
+
title.set('Updated via signal')
|
|
54
|
+
expect(document.title).toBe('Updated via signal')
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('nested components: inner useHead overrides outer title', () => {
|
|
58
|
+
function Inner() {
|
|
59
|
+
useHead({ title: 'Inner Title' })
|
|
60
|
+
return h('span', null)
|
|
61
|
+
}
|
|
62
|
+
function Outer() {
|
|
63
|
+
useHead({ title: 'Outer Title' })
|
|
64
|
+
return h('div', null, h(Inner, null))
|
|
65
|
+
}
|
|
66
|
+
mount(h(HeadProvider, { context: ctx, children: h(Outer, null) }), container)
|
|
67
|
+
expect(document.title).toBe('Inner Title')
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('unmount removes head tags', () => {
|
|
71
|
+
function Page() {
|
|
72
|
+
useHead({ meta: [{ name: 'keywords', content: 'pyreon,test' }] })
|
|
73
|
+
return h('div', null)
|
|
74
|
+
}
|
|
75
|
+
const cleanup = mount(
|
|
76
|
+
h(HeadProvider, { context: ctx, children: h(Page, null) }),
|
|
77
|
+
container,
|
|
78
|
+
)
|
|
79
|
+
expect(document.head.querySelector('meta[name="keywords"]')).not.toBeNull()
|
|
80
|
+
cleanup()
|
|
81
|
+
expect(document.head.querySelector('meta[name="keywords"]')).toBeNull()
|
|
82
|
+
})
|
|
83
|
+
})
|