@adaas/are-html 0.0.12 → 0.0.13

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 (108) hide show
  1. package/dist/browser/index.d.mts +19 -4
  2. package/dist/browser/index.mjs +104 -7
  3. package/dist/browser/index.mjs.map +1 -1
  4. package/dist/node/{AreBinding.attribute-C6JasbJL.d.ts → AreBinding.attribute-Bm5LlOyE.d.ts} +7 -0
  5. package/dist/node/{AreBinding.attribute-C6qrxN8K.d.mts → AreBinding.attribute-doUvtOjc.d.mts} +7 -0
  6. package/dist/node/attributes/AreBinding.attribute.d.mts +1 -1
  7. package/dist/node/attributes/AreBinding.attribute.d.ts +1 -1
  8. package/dist/node/attributes/AreDirective.attribute.d.mts +1 -1
  9. package/dist/node/attributes/AreDirective.attribute.d.ts +1 -1
  10. package/dist/node/attributes/AreEvent.attribute.d.mts +1 -1
  11. package/dist/node/attributes/AreEvent.attribute.d.ts +1 -1
  12. package/dist/node/attributes/AreStatic.attribute.d.mts +1 -1
  13. package/dist/node/attributes/AreStatic.attribute.d.ts +1 -1
  14. package/dist/node/directives/AreDirectiveFor.directive.d.mts +1 -1
  15. package/dist/node/directives/AreDirectiveFor.directive.d.ts +1 -1
  16. package/dist/node/directives/AreDirectiveIf.directive.d.mts +1 -1
  17. package/dist/node/directives/AreDirectiveIf.directive.d.ts +1 -1
  18. package/dist/node/engine/AreHTML.compiler.d.mts +8 -1
  19. package/dist/node/engine/AreHTML.compiler.d.ts +8 -1
  20. package/dist/node/engine/AreHTML.compiler.js +17 -0
  21. package/dist/node/engine/AreHTML.compiler.js.map +1 -1
  22. package/dist/node/engine/AreHTML.compiler.mjs +17 -0
  23. package/dist/node/engine/AreHTML.compiler.mjs.map +1 -1
  24. package/dist/node/engine/AreHTML.context.js +2 -2
  25. package/dist/node/engine/AreHTML.context.js.map +1 -1
  26. package/dist/node/engine/AreHTML.context.mjs +3 -3
  27. package/dist/node/engine/AreHTML.context.mjs.map +1 -1
  28. package/dist/node/engine/AreHTML.interpreter.d.mts +3 -0
  29. package/dist/node/engine/AreHTML.interpreter.d.ts +3 -0
  30. package/dist/node/engine/AreHTML.interpreter.js +44 -0
  31. package/dist/node/engine/AreHTML.interpreter.js.map +1 -1
  32. package/dist/node/engine/AreHTML.interpreter.mjs +44 -0
  33. package/dist/node/engine/AreHTML.interpreter.mjs.map +1 -1
  34. package/dist/node/engine/AreHTML.lifecycle.d.mts +2 -1
  35. package/dist/node/engine/AreHTML.lifecycle.d.ts +2 -1
  36. package/dist/node/engine/AreHTML.lifecycle.js +13 -1
  37. package/dist/node/engine/AreHTML.lifecycle.js.map +1 -1
  38. package/dist/node/engine/AreHTML.lifecycle.mjs +13 -1
  39. package/dist/node/engine/AreHTML.lifecycle.mjs.map +1 -1
  40. package/dist/node/engine/AreHTML.tokenizer.d.mts +1 -1
  41. package/dist/node/engine/AreHTML.tokenizer.d.ts +1 -1
  42. package/dist/node/engine/AreHTML.transformer.d.mts +1 -1
  43. package/dist/node/engine/AreHTML.transformer.d.ts +1 -1
  44. package/dist/node/index.d.mts +1 -1
  45. package/dist/node/index.d.ts +1 -1
  46. package/dist/node/instructions/AreHTML.instructions.types.d.mts +2 -4
  47. package/dist/node/instructions/AreHTML.instructions.types.d.ts +2 -4
  48. package/dist/node/lib/AreDirective/AreDirective.component.d.mts +1 -1
  49. package/dist/node/lib/AreDirective/AreDirective.component.d.ts +1 -1
  50. package/dist/node/lib/AreDirective/AreDirective.types.d.mts +1 -1
  51. package/dist/node/lib/AreDirective/AreDirective.types.d.ts +1 -1
  52. package/dist/node/lib/AreHTML/AreHTML.tokenizer.d.mts +1 -1
  53. package/dist/node/lib/AreHTML/AreHTML.tokenizer.d.ts +1 -1
  54. package/dist/node/lib/AreHTMLAttribute/AreHTML.attribute.d.mts +1 -1
  55. package/dist/node/lib/AreHTMLAttribute/AreHTML.attribute.d.ts +1 -1
  56. package/dist/node/lib/AreHTMLNode/AreHTMLNode.d.mts +1 -1
  57. package/dist/node/lib/AreHTMLNode/AreHTMLNode.d.ts +1 -1
  58. package/dist/node/lib/AreHTMLNode/AreHTMLNode.js +14 -0
  59. package/dist/node/lib/AreHTMLNode/AreHTMLNode.js.map +1 -1
  60. package/dist/node/lib/AreHTMLNode/AreHTMLNode.mjs +14 -0
  61. package/dist/node/lib/AreHTMLNode/AreHTMLNode.mjs.map +1 -1
  62. package/dist/node/lib/AreRoot/AreRoot.component.js +16 -3
  63. package/dist/node/lib/AreRoot/AreRoot.component.js.map +1 -1
  64. package/dist/node/lib/AreRoot/AreRoot.component.mjs +16 -3
  65. package/dist/node/lib/AreRoot/AreRoot.component.mjs.map +1 -1
  66. package/dist/node/nodes/AreComment.d.mts +1 -1
  67. package/dist/node/nodes/AreComment.d.ts +1 -1
  68. package/dist/node/nodes/AreComponent.d.mts +1 -1
  69. package/dist/node/nodes/AreComponent.d.ts +1 -1
  70. package/dist/node/nodes/AreInterpolation.d.mts +1 -1
  71. package/dist/node/nodes/AreInterpolation.d.ts +1 -1
  72. package/dist/node/nodes/AreRoot.d.mts +1 -1
  73. package/dist/node/nodes/AreRoot.d.ts +1 -1
  74. package/dist/node/nodes/AreText.d.mts +1 -1
  75. package/dist/node/nodes/AreText.d.ts +1 -1
  76. package/examples/component-styles/concept.ts +41 -0
  77. package/examples/component-styles/containers/UI.container.ts +122 -0
  78. package/examples/component-styles/dist/index.html +25 -0
  79. package/examples/{jumpstart/dist/mor90p6y-0plg7g.js → component-styles/dist/mpq29j47-owas2v.js} +8326 -5942
  80. package/examples/component-styles/public/index.html +25 -0
  81. package/examples/component-styles/src/components/AppPage.component.ts +74 -0
  82. package/examples/component-styles/src/components/TheAlert.component.ts +81 -0
  83. package/examples/component-styles/src/components/TheButton.component.ts +71 -0
  84. package/examples/component-styles/src/components/TheCard.component.ts +64 -0
  85. package/examples/component-styles/src/concept.ts +70 -0
  86. package/examples/dashboard/dist/index.html +1 -1
  87. package/examples/dashboard/dist/{mpmt0gys-1r9rcu.js → mppzjw80-9gwa4h.js} +1223 -863
  88. package/examples/jumpstart/dist/index.html +1 -1
  89. package/examples/jumpstart/dist/{mor90p7p-1898bz.js → mppwx932-xbmb0x.js} +4215 -1984
  90. package/examples/signal-routing/concept.ts +41 -0
  91. package/examples/signal-routing/containers/UI.container.ts +126 -0
  92. package/examples/signal-routing/dist/index.html +18 -0
  93. package/examples/signal-routing/dist/mpq6u1wz-2pkqe2.js +14002 -0
  94. package/examples/signal-routing/public/index.html +18 -0
  95. package/examples/signal-routing/src/components/AboutPage.component.ts +74 -0
  96. package/examples/signal-routing/src/components/AppShell.component.ts +42 -0
  97. package/examples/signal-routing/src/components/HomePage.component.ts +76 -0
  98. package/examples/signal-routing/src/components/NavBar.component.ts +104 -0
  99. package/examples/signal-routing/src/components/SettingsPage.component.ts +98 -0
  100. package/examples/signal-routing/src/concept.ts +114 -0
  101. package/package.json +7 -5
  102. package/src/engine/AreHTML.compiler.ts +24 -7
  103. package/src/engine/AreHTML.context.ts +6 -4
  104. package/src/engine/AreHTML.interpreter.ts +54 -0
  105. package/src/engine/AreHTML.lifecycle.ts +16 -12
  106. package/src/instructions/AreHTML.instructions.types.ts +2 -4
  107. package/src/lib/AreHTMLNode/AreHTMLNode.ts +15 -0
  108. package/src/lib/AreRoot/AreRoot.component.ts +31 -7
@@ -14,6 +14,7 @@ import { AddCommentInstruction } from "@adaas/are-html/instructions/AddComment.i
14
14
  import { AddElementInstruction } from "@adaas/are-html/instructions/AddElement.instruction";
15
15
  import { AddListenerInstruction } from "@adaas/are-html/instructions/AddListener.instruction";
16
16
  import { AddTextInstruction } from "@adaas/are-html/instructions/AddText.instruction";
17
+ import { AddStyleInstruction } from "@adaas/are-html/instructions/AddStyle.instruction";
17
18
  import { AreDirectiveContext } from "@adaas/are-html/directive/AreDirective.context";
18
19
  import { AreHTMLNode } from "../lib/AreHTMLNode/AreHTMLNode";
19
20
  import { AreHTMLEngineContext } from "./AreHTML.context";
@@ -620,6 +621,59 @@ export class AreHTMLInterpreter extends AreInterpreter {
620
621
  context.removeInstructionElement(declaration);
621
622
  }
622
623
 
624
+ // ─────────────────────────────────────────────────────────────────────────────
625
+ // ── AddStyle — Apply / Update / Revert ───────────────────────────────────────
626
+ // ─────────────────────────────────────────────────────────────────────────────
627
+
628
+ @A_Frame.Define({
629
+ description: 'Inject a <style> element into the document <head> carrying the component CSS. Keyed by instruction ASEID so multiple components with styles do not collide. Subsequent Update calls refresh the textContent in-place.'
630
+ })
631
+ @AreInterpreter.Apply(AreHTMLInstructions.AddStyle)
632
+ @AreInterpreter.Update(AreHTMLInstructions.AddStyle)
633
+ addStyle(
634
+ @A_Inject(A_Caller) mutation: AddStyleInstruction,
635
+ @A_Inject(AreHTMLEngineContext) context: AreHTMLEngineContext,
636
+ @A_Inject(A_Logger) logger?: A_Logger,
637
+ ): void {
638
+ try {
639
+
640
+
641
+ const { styles } = mutation.payload;
642
+ const styleId = `are-style-${String(mutation.aseid)}`;
643
+
644
+ const existing = context.getElementByInstruction(mutation) as HTMLStyleElement | undefined;
645
+ if (existing) {
646
+ existing.textContent = styles;
647
+ } else {
648
+ const styleEl = context.container.createElement('style') as HTMLStyleElement;
649
+ styleEl.setAttribute('data-are-id', styleId);
650
+ styleEl.textContent = styles;
651
+ (context.container.head ?? context.container.body).appendChild(styleEl);
652
+
653
+ context.setInstructionElement(mutation, styleEl);
654
+ logger?.debug('green', `Style injected for ${String(mutation.aseid)}`);
655
+ }
656
+ } catch (error) {
657
+ logger?.error(error);
658
+ }
659
+
660
+ }
661
+
662
+ @A_Frame.Define({
663
+ description: 'Remove the <style> element that was injected by addStyle, cleaning up the document head.'
664
+ })
665
+ @AreInterpreter.Revert(AreHTMLInstructions.AddStyle)
666
+ removeStyle(
667
+ @A_Inject(A_Caller) mutation: AddStyleInstruction,
668
+ @A_Inject(AreHTMLEngineContext) context: AreHTMLEngineContext,
669
+ ): void {
670
+ const styleEl = context.getElementByInstruction(mutation);
671
+ if (styleEl?.parentNode) {
672
+ styleEl.parentNode.removeChild(styleEl);
673
+ }
674
+ context.removeInstructionElement(mutation);
675
+ }
676
+
623
677
  // ─────────────────────────────────────────────────────────────────────────────
624
678
  // ── SVG helpers ───────────────────────────────────────────────────────────────
625
679
  // ─────────────────────────────────────────────────────────────────────────────
@@ -19,7 +19,6 @@ import { A_Frame } from "@adaas/a-frame/core";
19
19
  export class AreHTMLLifecycle extends AreLifecycle {
20
20
 
21
21
  @AreLifecycle.Init(AreComponentNode)
22
- @AreLifecycle.Init(AreRootNode)
23
22
  initComponent(
24
23
  @A_Inject(A_Caller) node: AreHTMLNode,
25
24
  @A_Inject(A_Scope) scope: A_Scope,
@@ -28,21 +27,26 @@ export class AreHTMLLifecycle extends AreLifecycle {
28
27
  @A_Inject(A_Logger) logger?: A_Logger,
29
28
  ...args: any[]
30
29
  ): void {
31
- signalsContext?.subscribe(node);
30
+
31
+ if (node.component)
32
+ signalsContext?.subscribe(node);
33
+
32
34
  super.init(node, scope, context, logger, ...args);
33
35
  }
34
36
 
35
37
 
36
- // initRoot(
37
- // @A_Inject(A_Caller) node: AreHTMLNode,
38
- // @A_Inject(A_Scope) scope: A_Scope,
39
- // @A_Inject(AreHTMLEngineContext) context: AreHTMLEngineContext,
40
- // @A_Inject(AreSignalsContext) signalsContext?: AreSignalsContext,
41
- // @A_Inject(A_Logger) logger?: A_Logger,
42
- // ...args: any[]
43
- // ): void {
44
- // super.init(node, scope, context, logger, ...args);
45
- // }
38
+ @AreLifecycle.Init(AreRootNode)
39
+ initRoot(
40
+ @A_Inject(A_Caller) node: AreHTMLNode,
41
+ @A_Inject(A_Scope) scope: A_Scope,
42
+ @A_Inject(AreHTMLEngineContext) context: AreHTMLEngineContext,
43
+ @A_Inject(AreSignalsContext) signalsContext?: AreSignalsContext,
44
+ @A_Inject(A_Logger) logger?: A_Logger,
45
+ ...args: any[]
46
+ ): void {
47
+ signalsContext?.subscribe(node);
48
+ super.init(node, scope, context, logger, ...args);
49
+ }
46
50
 
47
51
 
48
52
  @AreLifecycle.Init(AreText)
@@ -30,10 +30,8 @@ export type AreHtmlAddCommentInstructionPayload = {
30
30
  }
31
31
 
32
32
  export type AreHtmlAddStyleInstructionPayload = {
33
- /** CSS property name in camelCase (e.g. "backgroundColor") or kebab-case (e.g. "background-color") */
34
- property: string;
35
- /** CSS property value */
36
- value: string;
33
+ /** Full CSS string to inject as a <style> block scoped to the component. Applied to the document head and reverted on unmount. */
34
+ styles: string;
37
35
  }
38
36
 
39
37
  export type AreHtmlAddListenerInstructionPayload = {
@@ -80,4 +80,19 @@ export class AreHTMLNode extends AreNode {
80
80
  return this.scope.resolveFlat<AreStyle>(AreStyle)!;
81
81
  }
82
82
 
83
+ /**
84
+ * Registers or updates the component-scoped CSS string for this node.
85
+ * Called by the @Are.Styles-decorated method on the associated component.
86
+ * A new AreStyle fragment is registered in scope on first call; subsequent
87
+ * calls update the existing fragment in-place.
88
+ */
89
+ setStyles(css: string): void {
90
+ const existing = this.scope.resolveFlat<AreStyle>(AreStyle);
91
+ if (existing) {
92
+ existing.styles = css;
93
+ } else {
94
+ this.scope.register(new AreStyle(css, this.aseid.toString()));
95
+ }
96
+ }
97
+
83
98
  }
@@ -2,7 +2,8 @@ import { A_Caller, A_Context, A_FormatterHelper, A_Inject, } from "@adaas/a-conc
2
2
  import { A_Frame } from "@adaas/a-frame/core";
3
3
  import { A_Logger } from "@adaas/a-utils/a-logger";
4
4
  import { A_SignalVector } from "@adaas/a-utils/a-signal";
5
- import { Are, ArePropDefinition, AreStore, AreNode, AreSignals, AreSignalsMeta, AreSignalsContext, AreRoute } from "@adaas/are";
5
+ import { Are, ArePropDefinition, AreStore, AreNode, AreSignals, AreSignalsMeta, AreSignalsContext } from "@adaas/are";
6
+ import { AreRoute } from "@adaas/are-html/signals/AreRoute.signal";
6
7
 
7
8
 
8
9
  @A_Frame.Define({
@@ -28,8 +29,18 @@ export class AreRoot extends Are {
28
29
 
29
30
  const rootId = root.id;
30
31
 
31
- // No routing config for this root — leave the existing template content intact
32
+ // No routing config for this root — but still honour body content or
33
+ // a 'default' attribute if one is present on the markup.
32
34
  if (signalsContext && !signalsContext.hasRoot(rootId)) {
35
+ if (!root.content?.trim()) {
36
+ // Fallback: legacy default= attribute
37
+ const defaultMatch = root.markup?.match(/\bdefault=["']([^"']*)["']/);
38
+ const defaultComponent = defaultMatch?.[1];
39
+ if (defaultComponent) {
40
+ root.setContent(`<${defaultComponent}></${defaultComponent}>`);
41
+ }
42
+ }
43
+ // Body content (or none) — tokenizer picks it up without intervention
33
44
  return;
34
45
  }
35
46
 
@@ -54,16 +65,23 @@ export class AreRoot extends Are {
54
65
  }
55
66
  }
56
67
 
57
- // 3. Fall back to the 'default' attribute on the node directly.
58
- // Note: root.attributes is NOT populated at this stage because tokenize()
59
- // runs after template() in the lifecycle. Read from raw markup instead.
68
+ // 3. Fall back to body content (the nodes already placed inside the
69
+ // <are-root> tag act as the default). No setContent() call needed —
70
+ // the tokenizer will process root.content as-is.
71
+ if (!componentName) {
72
+ if (root.content?.trim()) {
73
+ return;
74
+ }
75
+ }
76
+
77
+ // 4. Last resort: legacy default= attribute on the markup.
60
78
  if (!componentName) {
61
79
  const defaultMatch = root.markup?.match(/\bdefault=["']([^"']*)["']/);
62
80
  componentName = defaultMatch?.[1];
63
81
  }
64
82
 
65
83
  if (!componentName) {
66
- logger.warning('AreRoot: No component found for initial render. Please ensure a route condition or "default" attribute is set.');
84
+ logger.warning('AreRoot: No component found for initial render. Provide body content, a route condition, or a "default" attribute.');
67
85
  return;
68
86
  }
69
87
 
@@ -80,6 +98,7 @@ export class AreRoot extends Are {
80
98
  @A_Inject(AreSignalsContext) signalsContext?: AreSignalsContext,
81
99
  ) {
82
100
  const rootId = root.id;
101
+
83
102
  // No routing config for this root — signals do not affect its content
84
103
  if (signalsContext && !signalsContext.hasRoot(rootId)) {
85
104
  return;
@@ -98,15 +117,20 @@ export class AreRoot extends Are {
98
117
  ? A_FormatterHelper.toKebabCase(renderTarget.name)
99
118
  : store.get('default');
100
119
 
120
+ // No matching condition for this signal vector (e.g. AreInit before any route).
121
+ // Keep the current outlet content and do nothing.
101
122
  if (!componentName) {
102
- logger.warning('No component found for rendering in AreRoot. Please ensure that the signal vector matches at least one component or that a default component name is provided in the store.');
103
123
  return;
104
124
  }
105
125
 
106
126
  root.setContent(`<${componentName}></${componentName}>`);
107
127
 
128
+ // Unsubscribe old children BEFORE destroying them.
129
+ // Without this, AreSignals.handleSignalVector keeps iterating stale
130
+ // (scope-less) nodes on every subsequent signal and throws an error.
108
131
  for (let i = 0; i < root.children.length; i++) {
109
132
  const child = root.children[i];
133
+ signalsContext?.unsubscribe(child);
110
134
  child.unmount();
111
135
  child.destroy();
112
136
  root.removeChild(child);