@adukiorg/anza 0.3.8 → 0.4.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/CHANGELOG.md +20 -0
- package/bin/anza/anza-linux-arm64 +0 -0
- package/bin/anza/anza-linux-x64 +0 -0
- package/bin/anza/anza-macos-arm64 +0 -0
- package/bin/anza/anza-macos-x64 +0 -0
- package/bin/anza/anza-windows-x64.exe +0 -0
- package/package.json +1 -1
- package/src/core/ui/define/element.js +125 -19
- package/src/core/ui/define/utils.js +30 -22
- package/src/elements/data/card/style.css +1 -1
- package/src/elements/data/chart/style.css +1 -1
- package/src/elements/data/list/style.css +1 -1
- package/src/elements/data/stat/style.css +1 -1
- package/src/elements/data/table/style.css +1 -1
- package/src/elements/feedback/alert/style.css +1 -1
- package/src/elements/feedback/empty/style.css +1 -1
- package/src/elements/feedback/progress/style.css +1 -1
- package/src/elements/feedback/toast/style.css +1 -1
- package/src/elements/forms/checkbox/style.css +1 -1
- package/src/elements/forms/field/style.css +1 -1
- package/src/elements/forms/input/style.css +1 -1
- package/src/elements/forms/radio/style.css +1 -1
- package/src/elements/forms/select/style.css +1 -1
- package/src/elements/forms/textarea/style.css +1 -1
- package/src/elements/forms/toggle/style.css +1 -1
- package/src/elements/forms/upload/style.css +1 -1
- package/src/elements/layout/app/style.css +1 -1
- package/src/elements/navigation/breadcrumb/style.css +1 -1
- package/src/elements/navigation/nav/style.css +1 -1
- package/src/elements/navigation/pagination/style.css +1 -1
- package/src/elements/navigation/steps/style.css +1 -1
- package/src/elements/navigation/tabs/style.css +1 -1
- package/src/elements/overlay/dialog/style.css +1 -1
- package/src/elements/overlay/drawer/style.css +1 -1
- package/src/elements/overlay/menu/style.css +1 -1
- package/src/elements/overlay/popover/style.css +1 -1
- package/src/elements/overlay/sheet/style.css +1 -1
- package/src/elements/overlay/tooltip/style.css +1 -1
- package/src/elements/primitives/avatar/style.css +1 -1
- package/src/elements/primitives/badge/style.css +1 -1
- package/src/elements/primitives/button/style.css +1 -1
- package/src/elements/primitives/text/style.css +1 -1
- package/src/styles/base.css +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,26 @@ Versioning follows [Semantic Versioning](https://semver.org/).
|
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
+
## [0.4.0] — 2026-06-14
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- Natively support arrays of multiple CSS imports in component definitions (`template: { html, css: ['./a.css', './b.css'] }`) across both the JavaScript library runtime and the Rust compiler.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- Replaced CSS Custom Highlight API implementation with PrismJS for `view-code` syntax highlighting.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## [0.3.9] — 2026-06-13
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- Updated core component rendering to correctly process nested syntax logic and perform full syntax highlighting.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
20
40
|
## [0.3.7] — 2026-06-13
|
|
21
41
|
|
|
22
42
|
### Changed
|
|
Binary file
|
package/bin/anza/anza-linux-x64
CHANGED
|
Binary file
|
|
Binary file
|
package/bin/anza/anza-macos-x64
CHANGED
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseElement } from '../base.js';
|
|
2
2
|
import { scheduleFrame, yieldTask } from '../schedule.js';
|
|
3
3
|
import { router } from '../../router/index.js';
|
|
4
|
-
import { specRegistry, internalsMap, initializedMap, pendingUpdatesMap, updateScheduledMap } from './state.js';
|
|
4
|
+
import { specRegistry, internalsMap, initializedMap, pendingUpdatesMap, updateScheduledMap, assetCache } from './state.js';
|
|
5
5
|
import { preloadResources } from './utils.js';
|
|
6
6
|
import { createComponentContext } from './proxy.js';
|
|
7
7
|
|
|
@@ -50,40 +50,74 @@ export function element(tag, spec, base) {
|
|
|
50
50
|
warnMissingBase(tag, 'template', spec.template, base);
|
|
51
51
|
|
|
52
52
|
// Resolve absolute URLs relative to import.meta.url (base)
|
|
53
|
-
const
|
|
54
|
-
? new URL(
|
|
55
|
-
:
|
|
53
|
+
const styleUrls = Array.isArray(spec.style)
|
|
54
|
+
? spec.style.filter(s => s && base && (s.endsWith('.css') || s.startsWith('./') || s.startsWith('/'))).map(s => new URL(s, base).href)
|
|
55
|
+
: (spec.style && base && (spec.style.endsWith('.css') || spec.style.startsWith('./') || spec.style.startsWith('/'))
|
|
56
|
+
? [new URL(spec.style, base).href]
|
|
57
|
+
: []);
|
|
58
|
+
|
|
56
59
|
const templateUrl = spec.template && base && (spec.template.endsWith('.html') || spec.template.startsWith('./') || spec.template.startsWith('/'))
|
|
57
60
|
? new URL(spec.template, base).href
|
|
58
61
|
: null;
|
|
59
62
|
|
|
60
63
|
// Initiate resource fetching exactly once per component registration (R-06)
|
|
61
64
|
let resolved = null;
|
|
62
|
-
|
|
65
|
+
let resourcesPromise = preloadResources(tag, styleUrls, templateUrl, spec.template, spec.style).then(res => {
|
|
63
66
|
resolved = res;
|
|
64
67
|
return res;
|
|
65
68
|
});
|
|
66
69
|
|
|
67
70
|
// Handle hot reloading of constructable stylesheets (one global listener per unique styleUrl - R-05)
|
|
68
|
-
if (
|
|
71
|
+
if (styleUrls.length > 0 && typeof window !== 'undefined') {
|
|
69
72
|
if (!window.__native_hmr_listeners__) {
|
|
70
73
|
window.__native_hmr_listeners__ = new Set();
|
|
71
74
|
}
|
|
72
|
-
|
|
73
|
-
window.__native_hmr_listeners__.
|
|
75
|
+
for (const styleUrl of styleUrls) {
|
|
76
|
+
if (!window.__native_hmr_listeners__.has(styleUrl)) {
|
|
77
|
+
window.__native_hmr_listeners__.add(styleUrl);
|
|
78
|
+
const hmrHandler = async (e) => {
|
|
79
|
+
const { path: changedPath, css } = e.detail;
|
|
80
|
+
const absoluteChangedUrl = new URL(changedPath, window.location.origin).href;
|
|
81
|
+
|
|
82
|
+
if (styleUrl === absoluteChangedUrl || styleUrl.endsWith(changedPath)) {
|
|
83
|
+
const sheet = assetCache.get(styleUrl);
|
|
84
|
+
if (sheet && typeof sheet.replaceSync === 'function') {
|
|
85
|
+
sheet.replaceSync(css);
|
|
86
|
+
console.log(`[HMR] Shared AdoptedStyleSheet hot-swapped for <${tag}>`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
window.addEventListener('anza:hmr:css', hmrHandler);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Handle hot reloading of HTML templates
|
|
96
|
+
if (templateUrl && typeof window !== 'undefined') {
|
|
97
|
+
if (!window.__native_hmr_html_listeners__) {
|
|
98
|
+
window.__native_hmr_html_listeners__ = new Set();
|
|
99
|
+
}
|
|
100
|
+
if (!window.__native_hmr_html_listeners__.has(templateUrl)) {
|
|
101
|
+
window.__native_hmr_html_listeners__.add(templateUrl);
|
|
74
102
|
const hmrHandler = async (e) => {
|
|
75
|
-
const { path: changedPath,
|
|
103
|
+
const { path: changedPath, html } = e.detail;
|
|
76
104
|
const absoluteChangedUrl = new URL(changedPath, window.location.origin).href;
|
|
77
105
|
|
|
78
|
-
if (
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
res
|
|
82
|
-
|
|
83
|
-
|
|
106
|
+
if (templateUrl === absoluteChangedUrl || templateUrl.endsWith(changedPath)) {
|
|
107
|
+
// Re-parse HTML into the cached resolved object
|
|
108
|
+
resourcesPromise = preloadResources(tag, styleUrls, null, html, spec.style).then(res => {
|
|
109
|
+
resolved = res;
|
|
110
|
+
// Now re-bind instances!
|
|
111
|
+
const instances = window.__native_hmr_instances__?.get(tag) || [];
|
|
112
|
+
for (const instance of instances) {
|
|
113
|
+
if (instance.__hmr_rebind) instance.__hmr_rebind();
|
|
114
|
+
}
|
|
115
|
+
console.log(`[HMR] Template hot-swapped for <${tag}>`);
|
|
116
|
+
return res;
|
|
117
|
+
});
|
|
84
118
|
}
|
|
85
119
|
};
|
|
86
|
-
window.addEventListener('anza:hmr:
|
|
120
|
+
window.addEventListener('anza:hmr:html', hmrHandler);
|
|
87
121
|
}
|
|
88
122
|
}
|
|
89
123
|
|
|
@@ -98,6 +132,11 @@ export function element(tag, spec, base) {
|
|
|
98
132
|
pendingUpdatesMap.set(this, new Map());
|
|
99
133
|
updateScheduledMap.set(this, false);
|
|
100
134
|
|
|
135
|
+
if (typeof window !== 'undefined') {
|
|
136
|
+
if (!window.__native_hmr_instances__) window.__native_hmr_instances__ = new Map();
|
|
137
|
+
if (!window.__native_hmr_instances__.has(tag)) window.__native_hmr_instances__.set(tag, new Set());
|
|
138
|
+
}
|
|
139
|
+
|
|
101
140
|
if (spec.form) {
|
|
102
141
|
const internals = this.attachInternals();
|
|
103
142
|
internalsMap.set(this, internals);
|
|
@@ -126,12 +165,16 @@ export function element(tag, spec, base) {
|
|
|
126
165
|
// AbortController bootstrap inside BaseElement
|
|
127
166
|
super.connectedCallback();
|
|
128
167
|
|
|
168
|
+
if (typeof window !== 'undefined') {
|
|
169
|
+
window.__native_hmr_instances__?.get(tag)?.add(this);
|
|
170
|
+
}
|
|
171
|
+
|
|
129
172
|
// Wait for resolved resources to compile (synchronously if already cached)
|
|
130
173
|
let res = resolved;
|
|
131
174
|
if (!res) {
|
|
132
175
|
res = await resourcesPromise;
|
|
133
176
|
}
|
|
134
|
-
const { templateNode,
|
|
177
|
+
const { templateNode, stylesheets, cssText, tagsDescriptor } = res;
|
|
135
178
|
|
|
136
179
|
if (!this.ctrl || this.ctrl.signal.aborted || !this.isConnected) {
|
|
137
180
|
return;
|
|
@@ -148,9 +191,9 @@ export function element(tag, spec, base) {
|
|
|
148
191
|
this.shadowRoot.appendChild(templateNode.cloneNode(true));
|
|
149
192
|
}
|
|
150
193
|
|
|
151
|
-
if (
|
|
194
|
+
if (stylesheets && stylesheets.length > 0) {
|
|
152
195
|
// Constructable stylesheets path
|
|
153
|
-
this.shadowRoot.adoptedStyleSheets =
|
|
196
|
+
this.shadowRoot.adoptedStyleSheets = stylesheets;
|
|
154
197
|
} else if (cssText) {
|
|
155
198
|
// Fallback: inject <style> for browsers without adoptedStyleSheets
|
|
156
199
|
const style = document.createElement('style');
|
|
@@ -190,6 +233,9 @@ export function element(tag, spec, base) {
|
|
|
190
233
|
}
|
|
191
234
|
|
|
192
235
|
disconnectedCallback() {
|
|
236
|
+
if (typeof window !== 'undefined') {
|
|
237
|
+
window.__native_hmr_instances__?.get(tag)?.delete(this);
|
|
238
|
+
}
|
|
193
239
|
if (spec.unmount) {
|
|
194
240
|
spec.unmount({
|
|
195
241
|
el: this,
|
|
@@ -202,6 +248,66 @@ export function element(tag, spec, base) {
|
|
|
202
248
|
super.disconnectedCallback();
|
|
203
249
|
}
|
|
204
250
|
|
|
251
|
+
async __hmr_rebind() {
|
|
252
|
+
// 1. Unmount component safely
|
|
253
|
+
if (spec.unmount) {
|
|
254
|
+
spec.unmount({
|
|
255
|
+
el: this,
|
|
256
|
+
tags: this._tags,
|
|
257
|
+
refs: this._refs,
|
|
258
|
+
watch: this._watch,
|
|
259
|
+
internals: internalsMap.get(this)
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// 2. Clear Shadow DOM
|
|
264
|
+
this.shadowRoot.innerHTML = '';
|
|
265
|
+
|
|
266
|
+
// 3. Clone new template
|
|
267
|
+
let res = resolved;
|
|
268
|
+
if (!res) {
|
|
269
|
+
res = await resourcesPromise;
|
|
270
|
+
}
|
|
271
|
+
const { templateNode, stylesheets, cssText, tagsDescriptor } = res;
|
|
272
|
+
|
|
273
|
+
if (templateNode) {
|
|
274
|
+
this.shadowRoot.appendChild(templateNode.cloneNode(true));
|
|
275
|
+
}
|
|
276
|
+
if (stylesheets && stylesheets.length > 0) {
|
|
277
|
+
this.shadowRoot.adoptedStyleSheets = stylesheets;
|
|
278
|
+
} else if (cssText) {
|
|
279
|
+
const style = document.createElement('style');
|
|
280
|
+
style.textContent = cssText;
|
|
281
|
+
this.shadowRoot.prepend(style);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// 4. Recreate component context to rebind DOM events and tags
|
|
285
|
+
const context = createComponentContext({
|
|
286
|
+
el: this,
|
|
287
|
+
shadowRoot: this.shadowRoot,
|
|
288
|
+
ctrl: this.ctrl,
|
|
289
|
+
descriptor: tagsDescriptor,
|
|
290
|
+
internals: internalsMap.get(this)
|
|
291
|
+
});
|
|
292
|
+
this._ctx = context;
|
|
293
|
+
this._tags = context.tags;
|
|
294
|
+
this._on = context.on;
|
|
295
|
+
this._refs = context.refs;
|
|
296
|
+
this._watch = context.watch;
|
|
297
|
+
|
|
298
|
+
// 5. Trigger mount again
|
|
299
|
+
if (spec.mount) {
|
|
300
|
+
try {
|
|
301
|
+
const mountRes = spec.mount(context);
|
|
302
|
+
if (mountRes instanceof Promise) {
|
|
303
|
+
mountRes.catch(console.error);
|
|
304
|
+
}
|
|
305
|
+
} catch (err) {
|
|
306
|
+
console.error('[Native UI] mount failed during HMR:', err);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
205
311
|
attributeChangedCallback(name, oldVal, newVal) {
|
|
206
312
|
if (oldVal === newVal) return;
|
|
207
313
|
|
|
@@ -8,52 +8,60 @@ const supportsSheets =
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Preloads style and HTML template resources asynchronously exactly once.
|
|
11
|
-
* Returns { templateNode,
|
|
12
|
-
* When constructable stylesheets are unsupported,
|
|
13
|
-
* cssText carries the raw CSS for <style> injection.
|
|
11
|
+
* Returns { templateNode, stylesheets, cssText, tagsDescriptor }.
|
|
12
|
+
* When constructable stylesheets are unsupported, stylesheets is an empty array and
|
|
13
|
+
* cssText carries the concatenated raw CSS for <style> injection.
|
|
14
14
|
*/
|
|
15
|
-
export async function preloadResources(tag,
|
|
15
|
+
export async function preloadResources(tag, styleUrls, templateUrl, inlineTemplate, inlineStyle) {
|
|
16
16
|
let templateNode = null;
|
|
17
|
-
let
|
|
18
|
-
let
|
|
17
|
+
let stylesheets = [];
|
|
18
|
+
let cssTextAcc = '';
|
|
19
19
|
let tagsDescriptor = null;
|
|
20
20
|
|
|
21
21
|
// Compile / Fetch styles
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
const urls = Array.isArray(styleUrls) ? styleUrls : (styleUrls ? [styleUrls] : []);
|
|
23
|
+
|
|
24
|
+
await Promise.all(urls.map(async (url) => {
|
|
25
|
+
if (assetCache.has(url)) {
|
|
26
|
+
const cached = assetCache.get(url);
|
|
25
27
|
if (supportsSheets) {
|
|
26
|
-
|
|
28
|
+
stylesheets.push(cached);
|
|
27
29
|
} else {
|
|
28
|
-
|
|
30
|
+
cssTextAcc += cached + '\n';
|
|
29
31
|
}
|
|
30
32
|
} else {
|
|
31
33
|
try {
|
|
32
|
-
const res = await fetch(
|
|
34
|
+
const res = await fetch(url);
|
|
33
35
|
if (res.ok) {
|
|
34
36
|
const css = await res.text();
|
|
35
37
|
if (supportsSheets) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
assetCache.set(
|
|
38
|
+
const sheet = new CSSStyleSheet();
|
|
39
|
+
sheet.replaceSync(css);
|
|
40
|
+
assetCache.set(url, sheet);
|
|
41
|
+
stylesheets.push(sheet);
|
|
39
42
|
} else {
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
assetCache.set(url, css);
|
|
44
|
+
cssTextAcc += css + '\n';
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
47
|
} catch (err) {
|
|
45
|
-
console.error(`Failed to load style resource for element ${tag}:`, err);
|
|
48
|
+
console.error(`Failed to load style resource ${url} for element ${tag}:`, err);
|
|
46
49
|
}
|
|
47
50
|
}
|
|
48
|
-
}
|
|
51
|
+
}));
|
|
52
|
+
|
|
53
|
+
if (inlineStyle) {
|
|
49
54
|
if (supportsSheets) {
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
const sheet = new CSSStyleSheet();
|
|
56
|
+
sheet.replaceSync(inlineStyle);
|
|
57
|
+
stylesheets.push(sheet);
|
|
52
58
|
} else {
|
|
53
|
-
|
|
59
|
+
cssTextAcc += inlineStyle + '\n';
|
|
54
60
|
}
|
|
55
61
|
}
|
|
56
62
|
|
|
63
|
+
const cssText = cssTextAcc.trim() ? cssTextAcc : null;
|
|
64
|
+
|
|
57
65
|
// Compile / Fetch Template markup
|
|
58
66
|
if (templateUrl) {
|
|
59
67
|
if (assetCache.has(templateUrl)) {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
border-radius: var(--radius-lg);
|
|
7
7
|
box-shadow: var(--shadow-sm);
|
|
8
8
|
overflow: hidden;
|
|
9
|
-
font-family: var(--font-
|
|
9
|
+
font-family: var(--font-sans);
|
|
10
10
|
transition:
|
|
11
11
|
transform var(--duration-fast) var(--ease-out),
|
|
12
12
|
box-shadow var(--duration-fast) var(--ease-out),
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
padding: var(--space-1) var(--space-2);
|
|
23
23
|
border-radius: var(--radius-sm);
|
|
24
24
|
font-size: var(--font-size-xs);
|
|
25
|
-
font-family: var(--font-
|
|
25
|
+
font-family: var(--font-sans);
|
|
26
26
|
white-space: nowrap;
|
|
27
27
|
box-shadow: var(--shadow-sm);
|
|
28
28
|
transition:
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
overflow: hidden;
|
|
11
11
|
background: var(--color-interactive-disabled);
|
|
12
12
|
color: var(--color-content-secondary);
|
|
13
|
-
font-family: var(--font-
|
|
13
|
+
font-family: var(--font-sans);
|
|
14
14
|
font-size: calc(var(--avatar-size, var(--space-8)) * 0.4);
|
|
15
15
|
font-weight: var(--font-weight-medium);
|
|
16
16
|
user-select: none;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
display: inline-flex;
|
|
5
5
|
/* Component Tokens — Semantic Reference Only */
|
|
6
6
|
--badge-radius: var(--radius-full);
|
|
7
|
-
--badge-font: var(--font-
|
|
7
|
+
--badge-font: var(--font-sans);
|
|
8
8
|
--badge-weight: var(--font-weight-semibold);
|
|
9
9
|
--badge-size: var(--font-size-xs);
|
|
10
10
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
--btn-bg-disabled: var(--color-interactive-disabled);
|
|
11
11
|
--btn-color: var(--color-content-inverse);
|
|
12
12
|
--btn-radius: var(--radius-md);
|
|
13
|
-
--btn-font: var(--font-
|
|
13
|
+
--btn-font: var(--font-sans);
|
|
14
14
|
--btn-size: var(--font-size-sm);
|
|
15
15
|
--btn-weight: var(--font-weight-medium);
|
|
16
16
|
--btn-padding-y: var(--space-2);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
/* Component Tokens — Semantic Reference Only */
|
|
6
6
|
--text-size: var(--font-size-base);
|
|
7
7
|
--text-weight: var(--font-weight-regular);
|
|
8
|
-
--text-family: var(--font-
|
|
8
|
+
--text-family: var(--font-sans);
|
|
9
9
|
--text-height: var(--line-height-normal);
|
|
10
10
|
--text-color: var(--color-content-primary);
|
|
11
11
|
}
|
package/src/styles/base.css
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
@layer base {
|
|
10
10
|
:root {
|
|
11
|
-
font-family: var(--font-
|
|
11
|
+
font-family: var(--font-sans);
|
|
12
12
|
font-size: var(--font-size-base);
|
|
13
13
|
color-scheme: light dark;
|
|
14
14
|
}
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
/* Typography Defaults */
|
|
26
26
|
h1, h2, h3, h4, h5, h6 {
|
|
27
|
-
font-family: var(--font-
|
|
27
|
+
font-family: var(--font-sans);
|
|
28
28
|
color: var(--color-content-primary);
|
|
29
29
|
font-weight: var(--font-weight-semibold);
|
|
30
30
|
line-height: var(--line-height-tight);
|