@zenithbuild/core 0.6.2 → 1.1.0
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/cli/commands/dev.ts +107 -48
- package/compiler/discovery/componentDiscovery.ts +75 -11
- package/compiler/output/types.ts +15 -1
- package/compiler/parse/parseTemplate.ts +29 -0
- package/compiler/runtime/dataExposure.ts +27 -12
- package/compiler/runtime/generateDOM.ts +12 -3
- package/compiler/runtime/transformIR.ts +39 -3
- package/compiler/runtime/wrapExpression.ts +32 -13
- package/compiler/runtime/wrapExpressionWithLoop.ts +24 -10
- package/compiler/ssg-build.ts +71 -7
- package/compiler/test/component-stacking.test.ts +365 -0
- package/compiler/transform/componentResolver.ts +42 -4
- package/compiler/transform/fragmentLowering.ts +153 -1
- package/compiler/transform/generateBindings.ts +31 -10
- package/compiler/transform/transformNode.ts +114 -1
- package/core/config/index.ts +5 -3
- package/core/config/types.ts +67 -37
- package/core/plugins/bridge.ts +193 -0
- package/core/plugins/registry.ts +51 -6
- package/dist/cli.js +10 -0
- package/dist/zen-build.js +673 -1723
- package/dist/zen-dev.js +673 -1723
- package/dist/zen-preview.js +673 -1723
- package/dist/zenith.js +673 -1723
- package/package.json +11 -3
- package/runtime/bundle-generator.ts +36 -17
- package/runtime/client-runtime.ts +21 -1
- package/cli/utils/content.ts +0 -112
- package/router/manifest.ts +0 -314
- package/router/navigation/ZenLink.zen +0 -231
- package/router/navigation/index.ts +0 -78
- package/router/navigation/zen-link.ts +0 -584
- package/router/runtime.ts +0 -458
- package/router/types.ts +0 -168
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
// Props extend HTMLAnchorElement properties + custom ZenLink attributes
|
|
3
|
-
// Standard anchor attributes: href, target, rel, download, hreflang, type, ping, referrerPolicy, etc.
|
|
4
|
-
// Custom ZenLink attributes: preload, exact, onClick
|
|
5
|
-
type Props = {
|
|
6
|
-
// Standard HTMLAnchorElement attributes
|
|
7
|
-
href?: string
|
|
8
|
-
target?: '_blank' | '_self' | '_parent' | '_top' | string
|
|
9
|
-
rel?: string
|
|
10
|
-
download?: string | boolean
|
|
11
|
-
hreflang?: string
|
|
12
|
-
type?: string
|
|
13
|
-
ping?: string
|
|
14
|
-
referrerPolicy?: string
|
|
15
|
-
class?: string
|
|
16
|
-
id?: string
|
|
17
|
-
title?: string
|
|
18
|
-
ariaLabel?: string
|
|
19
|
-
role?: string
|
|
20
|
-
tabIndex?: number | string
|
|
21
|
-
// Custom ZenLink attributes
|
|
22
|
-
preload?: boolean
|
|
23
|
-
exact?: boolean
|
|
24
|
-
onClick?: (event?: MouseEvent) => void | boolean
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Handle link click - prevents default and uses SPA navigation
|
|
29
|
-
* Respects target="_blank" and other standard anchor behaviors
|
|
30
|
-
*/
|
|
31
|
-
function handleClick(event, el) {
|
|
32
|
-
// Ensure attributes are set from props
|
|
33
|
-
if (el) {
|
|
34
|
-
ensureAttributes(el)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Get target from the element attribute (more reliable than prop)
|
|
38
|
-
const linkTarget = el ? el.getAttribute('target') : (typeof target !== 'undefined' ? target : null)
|
|
39
|
-
|
|
40
|
-
// If target is _blank, _parent, or _top, let browser handle it (opens in new tab/window)
|
|
41
|
-
if (linkTarget === '_blank' || linkTarget === '_parent' || linkTarget === '_top') {
|
|
42
|
-
// Let browser handle standard navigation
|
|
43
|
-
return
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Allow modifier keys for native behavior (Cmd/Ctrl+click, etc.)
|
|
47
|
-
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
|
|
48
|
-
return
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Get href from element or prop
|
|
52
|
-
const linkHref = el ? el.getAttribute('href') : (typeof href !== 'undefined' ? href : null)
|
|
53
|
-
if (!linkHref) return
|
|
54
|
-
|
|
55
|
-
// Check if external URL (http://, https://, //, mailto:, tel:, etc.)
|
|
56
|
-
if (linkHref.startsWith('http://') ||
|
|
57
|
-
linkHref.startsWith('https://') ||
|
|
58
|
-
linkHref.startsWith('//') ||
|
|
59
|
-
linkHref.startsWith('mailto:') ||
|
|
60
|
-
linkHref.startsWith('tel:') ||
|
|
61
|
-
linkHref.startsWith('javascript:')) {
|
|
62
|
-
// External/special link - open in new tab if target not specified
|
|
63
|
-
if (!linkTarget) {
|
|
64
|
-
el?.setAttribute('target', '_blank')
|
|
65
|
-
el?.setAttribute('rel', 'noopener noreferrer')
|
|
66
|
-
}
|
|
67
|
-
// Let browser handle it
|
|
68
|
-
return
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Prevent default navigation for internal SPA links
|
|
72
|
-
event.preventDefault()
|
|
73
|
-
event.stopPropagation()
|
|
74
|
-
|
|
75
|
-
// Call onClick prop if provided
|
|
76
|
-
if (typeof onClick === 'function') {
|
|
77
|
-
const result = onClick(event)
|
|
78
|
-
// If onClick returns false, cancel navigation
|
|
79
|
-
if (result === false) {
|
|
80
|
-
return
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Normalize path for comparison
|
|
85
|
-
const normalizedHref = linkHref === '' ? '/' : linkHref
|
|
86
|
-
const currentPath = window.location.pathname === '' ? '/' : window.location.pathname
|
|
87
|
-
|
|
88
|
-
// Only navigate if path is different (idempotent navigation)
|
|
89
|
-
if (normalizedHref !== currentPath) {
|
|
90
|
-
console.log('[ZenLink] Navigating to:', linkHref)
|
|
91
|
-
// Navigate using SPA router
|
|
92
|
-
if (window.__zenith_router && window.__zenith_router.navigate) {
|
|
93
|
-
console.log('[ZenLink] Using router.navigate')
|
|
94
|
-
window.__zenith_router.navigate(linkHref)
|
|
95
|
-
} else {
|
|
96
|
-
console.log('[ZenLink] Using fallback history API')
|
|
97
|
-
// Fallback to history API
|
|
98
|
-
window.history.pushState(null, '', linkHref)
|
|
99
|
-
window.dispatchEvent(new PopStateEvent('popstate'))
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
console.log('[ZenLink] Already on route:', linkHref, '- skipping navigation')
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Handle mouse enter for preloading
|
|
108
|
-
*/
|
|
109
|
-
function handleMouseEnter(event, el) {
|
|
110
|
-
// Ensure attributes are set
|
|
111
|
-
if (el) {
|
|
112
|
-
ensureAttributes(el)
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const shouldPreload = typeof preload !== 'undefined' ? preload : false
|
|
116
|
-
console.log('[ZenLink] handleMouseEnter called, preload:', shouldPreload)
|
|
117
|
-
if (!shouldPreload) {
|
|
118
|
-
console.log('[ZenLink] Preload disabled, returning early')
|
|
119
|
-
return
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const linkHref = el ? el.getAttribute('href') : (typeof href !== 'undefined' ? href : null)
|
|
123
|
-
if (!linkHref) {
|
|
124
|
-
return
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Skip external URLs
|
|
128
|
-
if (linkHref.startsWith('http://') || linkHref.startsWith('https://') || linkHref.startsWith('//')) {
|
|
129
|
-
return
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
console.log('[ZenLink] Prefetch triggered on hover:', linkHref)
|
|
133
|
-
|
|
134
|
-
// Prefetch the route
|
|
135
|
-
if (window.__zenith_router && window.__zenith_router.prefetch) {
|
|
136
|
-
console.log('[ZenLink] Calling router.prefetch for:', linkHref)
|
|
137
|
-
window.__zenith_router.prefetch(linkHref).then(() => {
|
|
138
|
-
console.log('[ZenLink] Prefetch complete for:', linkHref)
|
|
139
|
-
}).catch((error) => {
|
|
140
|
-
console.warn('[ZenLink] Prefetch failed for:', linkHref, error)
|
|
141
|
-
})
|
|
142
|
-
} else {
|
|
143
|
-
console.warn('[ZenLink] Router prefetch not available')
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Apply attributes on mount
|
|
148
|
-
if (typeof zenOnMount !== 'undefined') {
|
|
149
|
-
zenOnMount(() => {
|
|
150
|
-
setTimeout(() => {
|
|
151
|
-
// Find all ZenLink anchor elements and apply attributes
|
|
152
|
-
document.querySelectorAll('a[data-zen-component="Zenlink"]').forEach(el => {
|
|
153
|
-
ensureAttributes(el)
|
|
154
|
-
})
|
|
155
|
-
}, 0)
|
|
156
|
-
})
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Apply standard anchor attributes from props to the element
|
|
161
|
-
* Called when the element is clicked to ensure attributes are set
|
|
162
|
-
*/
|
|
163
|
-
function ensureAttributes(el) {
|
|
164
|
-
if (!el) return
|
|
165
|
-
|
|
166
|
-
// Set attributes from props (only if they exist and aren't already set)
|
|
167
|
-
const attrs = {
|
|
168
|
-
target: typeof target !== 'undefined' ? target : null,
|
|
169
|
-
rel: typeof rel !== 'undefined' ? rel : null,
|
|
170
|
-
download: typeof download !== 'undefined' ? download : null,
|
|
171
|
-
hreflang: typeof hreflang !== 'undefined' ? hreflang : null,
|
|
172
|
-
type: typeof type !== 'undefined' ? type : null,
|
|
173
|
-
ping: typeof ping !== 'undefined' ? ping : null,
|
|
174
|
-
referrerPolicy: typeof referrerPolicy !== 'undefined' ? referrerPolicy : null,
|
|
175
|
-
id: typeof id !== 'undefined' ? id : null,
|
|
176
|
-
title: typeof title !== 'undefined' ? title : null,
|
|
177
|
-
ariaLabel: typeof ariaLabel !== 'undefined' ? ariaLabel : null,
|
|
178
|
-
role: typeof role !== 'undefined' ? role : null,
|
|
179
|
-
tabIndex: typeof tabIndex !== 'undefined' ? tabIndex : null
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Map to HTML attribute names
|
|
183
|
-
const htmlAttrs = {
|
|
184
|
-
target: 'target',
|
|
185
|
-
rel: 'rel',
|
|
186
|
-
download: 'download',
|
|
187
|
-
hreflang: 'hreflang',
|
|
188
|
-
type: 'type',
|
|
189
|
-
ping: 'ping',
|
|
190
|
-
referrerPolicy: 'referrerpolicy',
|
|
191
|
-
id: 'id',
|
|
192
|
-
title: 'title',
|
|
193
|
-
ariaLabel: 'aria-label',
|
|
194
|
-
role: 'role',
|
|
195
|
-
tabIndex: 'tabindex'
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// Set attributes that have values
|
|
199
|
-
for (const [prop, value] of Object.entries(attrs)) {
|
|
200
|
-
if (value !== null && value !== undefined && value !== '') {
|
|
201
|
-
const htmlAttr = htmlAttrs[prop]
|
|
202
|
-
if (htmlAttr && !el.hasAttribute(htmlAttr)) {
|
|
203
|
-
el.setAttribute(htmlAttr, String(value))
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
</script>
|
|
210
|
-
|
|
211
|
-
<style>
|
|
212
|
-
.zen-link {
|
|
213
|
-
color: inherit;
|
|
214
|
-
text-decoration: none;
|
|
215
|
-
cursor: pointer;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
.zen-link:hover {
|
|
219
|
-
text-decoration: underline;
|
|
220
|
-
}
|
|
221
|
-
</style>
|
|
222
|
-
|
|
223
|
-
<a
|
|
224
|
-
href="{ href }"
|
|
225
|
-
class="zen-link { class }"
|
|
226
|
-
onclick="handleClick"
|
|
227
|
-
onmouseenter="handleMouseEnter"
|
|
228
|
-
style="cursor: pointer;"
|
|
229
|
-
>
|
|
230
|
-
<slot />
|
|
231
|
-
</a>
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Zenith Navigation System
|
|
3
|
-
*
|
|
4
|
-
* Provides SPA navigation utilities and the ZenLink API.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```ts
|
|
8
|
-
* import { navigate, isActive, prefetch, zenLink } from 'zenith/core'
|
|
9
|
-
*
|
|
10
|
-
* // Programmatic navigation
|
|
11
|
-
* navigate('/about')
|
|
12
|
-
*
|
|
13
|
-
* // Check active state
|
|
14
|
-
* if (isActive('/blog')) {
|
|
15
|
-
* console.log('On blog section')
|
|
16
|
-
* }
|
|
17
|
-
*
|
|
18
|
-
* // Prefetch for faster navigation
|
|
19
|
-
* prefetch('/dashboard')
|
|
20
|
-
*
|
|
21
|
-
* // Create link programmatically
|
|
22
|
-
* const link = zenLink({ href: '/contact', children: 'Contact' })
|
|
23
|
-
* ```
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
// Export all navigation utilities
|
|
27
|
-
export {
|
|
28
|
-
// Navigation API
|
|
29
|
-
zenNavigate,
|
|
30
|
-
navigate,
|
|
31
|
-
zenBack,
|
|
32
|
-
back,
|
|
33
|
-
zenForward,
|
|
34
|
-
forward,
|
|
35
|
-
zenGo,
|
|
36
|
-
go,
|
|
37
|
-
|
|
38
|
-
// Active state
|
|
39
|
-
zenIsActive,
|
|
40
|
-
isActive,
|
|
41
|
-
|
|
42
|
-
// Prefetching
|
|
43
|
-
zenPrefetch,
|
|
44
|
-
prefetch,
|
|
45
|
-
zenIsPrefetched,
|
|
46
|
-
isPrefetched,
|
|
47
|
-
|
|
48
|
-
// Transitions API
|
|
49
|
-
setGlobalTransition,
|
|
50
|
-
getGlobalTransition,
|
|
51
|
-
createTransitionContext,
|
|
52
|
-
|
|
53
|
-
// Route state
|
|
54
|
-
zenGetRoute,
|
|
55
|
-
getRoute,
|
|
56
|
-
zenGetParam,
|
|
57
|
-
getParam,
|
|
58
|
-
zenGetQuery,
|
|
59
|
-
getQuery,
|
|
60
|
-
|
|
61
|
-
// ZenLink factory
|
|
62
|
-
createZenLink,
|
|
63
|
-
zenLink,
|
|
64
|
-
|
|
65
|
-
// Utilities
|
|
66
|
-
isExternalUrl,
|
|
67
|
-
shouldUseSPANavigation,
|
|
68
|
-
normalizePath
|
|
69
|
-
} from './zen-link'
|
|
70
|
-
|
|
71
|
-
// Export types
|
|
72
|
-
export type {
|
|
73
|
-
ZenLinkProps,
|
|
74
|
-
TransitionContext,
|
|
75
|
-
TransitionHandler,
|
|
76
|
-
NavigateOptions
|
|
77
|
-
} from './zen-link'
|
|
78
|
-
|