@sprlab/wccompiler 0.13.0 → 0.14.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.
@@ -1,197 +1,197 @@
1
- /**
2
- * Angular adapter for WCC Scoped Slots and Event Binding.
3
- *
4
- * Exports:
5
- * - WccSlotDef: Auxiliary directive for ng-template[slot]
6
- * - WccSlotsDirective: Main directive activated via [wccSlots] attribute
7
- * - WccEvent: Single-event directive (wccEvent="name" + wccEmit output)
8
- * - WccEvents: Multi-event bridging directive (kebab-case → camelCase)
9
- * - SlotContext: Interface for template context typing
10
- *
11
- * Usage:
12
- * import { WccSlotsDirective, WccSlotDef, WccEvent, WccEvents } from '@sprlab/wccompiler/adapters/angular';
13
- *
14
- * @Component({
15
- * imports: [WccSlotsDirective, WccSlotDef, WccEvent, WccEvents],
16
- * schemas: [CUSTOM_ELEMENTS_SCHEMA],
17
- * template: `
18
- * <wcc-card wccSlots>
19
- * <ng-template slot="header"><strong>Header</strong></ng-template>
20
- * <ng-template slot="stats" let-likes>{{ likes }} likes</ng-template>
21
- * </wcc-card>
22
- *
23
- * <!-- Event binding option 1: single event with unwrapped detail -->
24
- * <wcc-counter wccEvent="count-changed" (wccEmit)="onCount($event)"></wcc-counter>
25
- *
26
- * <!-- Event binding option 2: camelCase event names -->
27
- * <wcc-counter wccEvents (countChanged)="onCount($event.detail)"></wcc-counter>
28
- *
29
- * <!-- Event binding option 3: standard Angular (always works) -->
30
- * <wcc-counter (count-changed)="onCount($event.detail)"></wcc-counter>
31
- * `
32
- * })
33
- *
34
- * Note: Add the `wccSlots` attribute to any WCC element that uses slots.
35
- * This is required because Angular AOT cannot evaluate dynamic selectors.
36
- *
37
- * @module @sprlab/wccompiler/adapters/angular
38
- */
39
- import { TemplateRef, QueryList, AfterContentInit, OnDestroy, OnInit, EventEmitter } from '@angular/core';
40
- import * as i0 from "@angular/core";
41
- /** Context object passed to createEmbeddedView for scoped slots */
42
- export interface SlotContext {
43
- $implicit: any;
44
- [key: string]: any;
45
- }
46
- /**
47
- * Auxiliary directive that marks an ng-template as slot content.
48
- * Captures the TemplateRef and the slot name from the HTML 'slot' attribute.
49
- *
50
- * Usage:
51
- * <ng-template slot="header">...</ng-template>
52
- * <ng-template slot="stats" let-likes>{{likes}}</ng-template>
53
- */
54
- export declare class WccSlotDef {
55
- readonly templateRef: TemplateRef<any>;
56
- readonly slotName: string;
57
- constructor(name: string | null);
58
- static ɵfac: i0.ɵɵFactoryDeclaration<WccSlotDef, [{ attribute: "slot"; }]>;
59
- static ɵdir: i0.ɵɵDirectiveDeclaration<WccSlotDef, "ng-template[slot]", never, {}, {}, never, never, true, never>;
60
- }
61
- /**
62
- * Main directive that activates on elements with the [wccSlots] attribute.
63
- * Classifies ng-template[slot] children as named or scoped slots and manages
64
- * their lifecycle.
65
- *
66
- * Uses a simple attribute selector `[wccSlots]` instead of a dynamic exclusion
67
- * selector, because Angular AOT cannot evaluate computed selector expressions.
68
- */
69
- export declare class WccSlotsDirective implements AfterContentInit, OnDestroy {
70
- slotDefs: QueryList<WccSlotDef>;
71
- private el;
72
- private vcr;
73
- private cdr;
74
- private slots;
75
- private eventCleanups;
76
- private destroyed;
77
- ngAfterContentInit(): void;
78
- ngOnDestroy(): void;
79
- /**
80
- * Normalizes Angular-style slot attributes to standard HTML slot attributes.
81
- * Converts: <div slot-header> → <div slot="header">
82
- *
83
- * This enables the Angular ng-content select pattern:
84
- * <wcc-card wccSlots>
85
- * <nav slot-header>Title</nav>
86
- * <span slot-footer>Footer</span>
87
- * </wcc-card>
88
- *
89
- * Skips reserved prefixes: slot-props, slot-template-*
90
- */
91
- private normalizeSlotAttributes;
92
- /** Classifies slots using __scopedSlots from the host element and initializes them */
93
- private classifyAndInitSlots;
94
- /** Named Slot: immediate static rendering */
95
- private initNamedSlot;
96
- /** Scoped Slot: registration + reactive rendering */
97
- private initScopedSlot;
98
- /**
99
- * Builds the Angular context for createEmbeddedView.
100
- *
101
- * Rules:
102
- * - 0 props: $implicit = undefined
103
- * - 1 prop: $implicit = that single value, plus the named prop key
104
- * - N props (N > 1): $implicit = full props object, plus all named props
105
- */
106
- buildContext(props: Record<string, any>): SlotContext;
107
- /** Creates or updates the EmbeddedView of a scoped slot */
108
- private renderSlot;
109
- /**
110
- * Inserts view root nodes into the custom element's DOM.
111
- *
112
- * Strategy:
113
- * 1. Look for a [data-slot="slotName"] element inside the component (non-Shadow DOM)
114
- * → clear its content and insert the rendered nodes there
115
- * 2. Fallback: append a wrapper <div slot="slotName"> to the host (Shadow DOM / native slots)
116
- */
117
- private insertView;
118
- /** Full cleanup on destroy */
119
- private cleanup;
120
- static ɵfac: i0.ɵɵFactoryDeclaration<WccSlotsDirective, never>;
121
- static ɵdir: i0.ɵɵDirectiveDeclaration<WccSlotsDirective, "[wccSlots]", never, {}, {}, ["slotDefs"], never, true, never>;
122
- }
123
- /**
124
- * Directive that bridges WCC custom element events to Angular output bindings.
125
- *
126
- * Problem: Angular's `(event-name)="handler($event)"` works on custom elements,
127
- * but `$event` is the raw CustomEvent. The developer must write `$event.detail`
128
- * to get the payload. This is verbose and error-prone.
129
- *
130
- * Solution: This directive listens for CustomEvents on the host element and
131
- * re-emits them as Angular outputs with `$event = event.detail`.
132
- *
133
- * Usage:
134
- * <wcc-counter wccEvent="count-changed" (wccEmit)="onCount($event)"></wcc-counter>
135
- *
136
- * Or for multiple events, use WccEvents (plural) with a comma-separated list:
137
- * <wcc-counter wccEvents="count-changed, value-changed"
138
- * (countChanged)="onCount($event)"
139
- * (valueChanged)="onValue($event)">
140
- * </wcc-counter>
141
- *
142
- * The event name is converted from kebab-case to camelCase for the output:
143
- * 'count-changed' → (countChanged)
144
- * 'value-changed' → (valueChanged)
145
- * 'change' → (change)
146
- */
147
- /**
148
- * Single-event directive: listens for one CustomEvent and emits its detail.
149
- *
150
- * Usage:
151
- * <wcc-counter wccEvent="count-changed" (wccEmit)="handler($event)"></wcc-counter>
152
- */
153
- export declare class WccEvent implements OnInit, OnDestroy {
154
- wccEvent: string;
155
- wccEmit: EventEmitter<any>;
156
- private el;
157
- private listener;
158
- ngOnInit(): void;
159
- ngOnDestroy(): void;
160
- static ɵfac: i0.ɵɵFactoryDeclaration<WccEvent, never>;
161
- static ɵdir: i0.ɵɵDirectiveDeclaration<WccEvent, "[wccEvent]", never, { "wccEvent": { "alias": "wccEvent"; "required": false; }; }, { "wccEmit": "wccEmit"; }, never, never, true, never>;
162
- }
163
- /**
164
- * Event bridging directive: allows using camelCase event bindings on WCC elements.
165
- *
166
- * Without this directive, Angular devs must use kebab-case event names:
167
- * <wcc-counter (count-changed)="onCount($event.detail)"></wcc-counter>
168
- *
169
- * With this directive, they can use camelCase (more Angular-idiomatic):
170
- * <wcc-counter wccEvents (countChanged)="onCount($event.detail)"></wcc-counter>
171
- *
172
- * The directive listens for kebab-case CustomEvents from the WCC component
173
- * and re-dispatches them with camelCase names so Angular's event binding picks them up.
174
- *
175
- * Event name conversion:
176
- * 'count-changed' → dispatches 'countChanged'
177
- * 'value-changed' → dispatches 'valueChanged'
178
- * 'change' → dispatches 'change' (no conversion needed)
179
- *
180
- * Event discovery:
181
- * - Auto: reads `static __events` from the WCC component class (set by codegen)
182
- * - Manual: pass an explicit array via [wccEvents]="['count-changed', 'value-changed']"
183
- *
184
- * Note: $event is still the CustomEvent — use $event.detail to get the payload.
185
- * This is consistent with how Angular handles all DOM events.
186
- */
187
- export declare class WccEvents implements OnInit, OnDestroy {
188
- /** Optional explicit list of kebab-case event names to bridge */
189
- wccEvents: string[] | '';
190
- private el;
191
- private listeners;
192
- ngOnInit(): void;
193
- private setupEvents;
194
- ngOnDestroy(): void;
195
- static ɵfac: i0.ɵɵFactoryDeclaration<WccEvents, never>;
196
- static ɵdir: i0.ɵɵDirectiveDeclaration<WccEvents, "[wccEvents]", never, { "wccEvents": { "alias": "wccEvents"; "required": false; }; }, {}, never, never, true, never>;
197
- }
1
+ /**
2
+ * Angular adapter for WCC Scoped Slots and Event Binding.
3
+ *
4
+ * Exports:
5
+ * - WccSlotDef: Auxiliary directive for ng-template[slot]
6
+ * - WccSlotsDirective: Main directive activated via [wccSlots] attribute
7
+ * - WccEvent: Single-event directive (wccEvent="name" + wccEmit output)
8
+ * - WccEvents: Multi-event bridging directive (kebab-case → camelCase)
9
+ * - SlotContext: Interface for template context typing
10
+ *
11
+ * Usage:
12
+ * import { WccSlotsDirective, WccSlotDef, WccEvent, WccEvents } from '@sprlab/wccompiler/adapters/angular';
13
+ *
14
+ * @Component({
15
+ * imports: [WccSlotsDirective, WccSlotDef, WccEvent, WccEvents],
16
+ * schemas: [CUSTOM_ELEMENTS_SCHEMA],
17
+ * template: `
18
+ * <wcc-card wccSlots>
19
+ * <ng-template slot="header"><strong>Header</strong></ng-template>
20
+ * <ng-template slot="stats" let-likes>{{ likes }} likes</ng-template>
21
+ * </wcc-card>
22
+ *
23
+ * <!-- Event binding option 1: single event with unwrapped detail -->
24
+ * <wcc-counter wccEvent="count-changed" (wccEmit)="onCount($event)"></wcc-counter>
25
+ *
26
+ * <!-- Event binding option 2: camelCase event names -->
27
+ * <wcc-counter wccEvents (countChanged)="onCount($event.detail)"></wcc-counter>
28
+ *
29
+ * <!-- Event binding option 3: standard Angular (always works) -->
30
+ * <wcc-counter (count-changed)="onCount($event.detail)"></wcc-counter>
31
+ * `
32
+ * })
33
+ *
34
+ * Note: Add the `wccSlots` attribute to any WCC element that uses slots.
35
+ * This is required because Angular AOT cannot evaluate dynamic selectors.
36
+ *
37
+ * @module @sprlab/wccompiler/adapters/angular
38
+ */
39
+ import { TemplateRef, QueryList, AfterContentInit, OnDestroy, OnInit, EventEmitter } from '@angular/core';
40
+ import * as i0 from "@angular/core";
41
+ /** Context object passed to createEmbeddedView for scoped slots */
42
+ export interface SlotContext {
43
+ $implicit: any;
44
+ [key: string]: any;
45
+ }
46
+ /**
47
+ * Auxiliary directive that marks an ng-template as slot content.
48
+ * Captures the TemplateRef and the slot name from the HTML 'slot' attribute.
49
+ *
50
+ * Usage:
51
+ * <ng-template slot="header">...</ng-template>
52
+ * <ng-template slot="stats" let-likes>{{likes}}</ng-template>
53
+ */
54
+ export declare class WccSlotDef {
55
+ readonly templateRef: TemplateRef<any>;
56
+ readonly slotName: string;
57
+ constructor(name: string | null);
58
+ static ɵfac: i0.ɵɵFactoryDeclaration<WccSlotDef, [{ attribute: "slot"; }]>;
59
+ static ɵdir: i0.ɵɵDirectiveDeclaration<WccSlotDef, "ng-template[slot]", never, {}, {}, never, never, true, never>;
60
+ }
61
+ /**
62
+ * Main directive that activates on elements with the [wccSlots] attribute.
63
+ * Classifies ng-template[slot] children as named or scoped slots and manages
64
+ * their lifecycle.
65
+ *
66
+ * Uses a simple attribute selector `[wccSlots]` instead of a dynamic exclusion
67
+ * selector, because Angular AOT cannot evaluate computed selector expressions.
68
+ */
69
+ export declare class WccSlotsDirective implements AfterContentInit, OnDestroy {
70
+ slotDefs: QueryList<WccSlotDef>;
71
+ private el;
72
+ private vcr;
73
+ private cdr;
74
+ private slots;
75
+ private eventCleanups;
76
+ private destroyed;
77
+ ngAfterContentInit(): void;
78
+ ngOnDestroy(): void;
79
+ /**
80
+ * Normalizes Angular-style slot attributes to standard HTML slot attributes.
81
+ * Converts: <div slot-header> → <div slot="header">
82
+ *
83
+ * This enables the Angular ng-content select pattern:
84
+ * <wcc-card wccSlots>
85
+ * <nav slot-header>Title</nav>
86
+ * <span slot-footer>Footer</span>
87
+ * </wcc-card>
88
+ *
89
+ * Skips reserved prefixes: slot-props, slot-template-*
90
+ */
91
+ private normalizeSlotAttributes;
92
+ /** Classifies slots using __scopedSlots from the host element and initializes them */
93
+ private classifyAndInitSlots;
94
+ /** Named Slot: immediate static rendering */
95
+ private initNamedSlot;
96
+ /** Scoped Slot: registration + reactive rendering */
97
+ private initScopedSlot;
98
+ /**
99
+ * Builds the Angular context for createEmbeddedView.
100
+ *
101
+ * Rules:
102
+ * - 0 props: $implicit = undefined
103
+ * - 1 prop: $implicit = that single value, plus the named prop key
104
+ * - N props (N > 1): $implicit = full props object, plus all named props
105
+ */
106
+ buildContext(props: Record<string, any>): SlotContext;
107
+ /** Creates or updates the EmbeddedView of a scoped slot */
108
+ private renderSlot;
109
+ /**
110
+ * Inserts view root nodes into the custom element's DOM.
111
+ *
112
+ * Strategy:
113
+ * 1. Look for a [data-slot="slotName"] element inside the component (non-Shadow DOM)
114
+ * → clear its content and insert the rendered nodes there
115
+ * 2. Fallback: append a wrapper <div slot="slotName"> to the host (Shadow DOM / native slots)
116
+ */
117
+ private insertView;
118
+ /** Full cleanup on destroy */
119
+ private cleanup;
120
+ static ɵfac: i0.ɵɵFactoryDeclaration<WccSlotsDirective, never>;
121
+ static ɵdir: i0.ɵɵDirectiveDeclaration<WccSlotsDirective, "[wccSlots]", never, {}, {}, ["slotDefs"], never, true, never>;
122
+ }
123
+ /**
124
+ * Directive that bridges WCC custom element events to Angular output bindings.
125
+ *
126
+ * Problem: Angular's `(event-name)="handler($event)"` works on custom elements,
127
+ * but `$event` is the raw CustomEvent. The developer must write `$event.detail`
128
+ * to get the payload. This is verbose and error-prone.
129
+ *
130
+ * Solution: This directive listens for CustomEvents on the host element and
131
+ * re-emits them as Angular outputs with `$event = event.detail`.
132
+ *
133
+ * Usage:
134
+ * <wcc-counter wccEvent="count-changed" (wccEmit)="onCount($event)"></wcc-counter>
135
+ *
136
+ * Or for multiple events, use WccEvents (plural) with a comma-separated list:
137
+ * <wcc-counter wccEvents="count-changed, value-changed"
138
+ * (countChanged)="onCount($event)"
139
+ * (valueChanged)="onValue($event)">
140
+ * </wcc-counter>
141
+ *
142
+ * The event name is converted from kebab-case to camelCase for the output:
143
+ * 'count-changed' → (countChanged)
144
+ * 'value-changed' → (valueChanged)
145
+ * 'change' → (change)
146
+ */
147
+ /**
148
+ * Single-event directive: listens for one CustomEvent and emits its detail.
149
+ *
150
+ * Usage:
151
+ * <wcc-counter wccEvent="count-changed" (wccEmit)="handler($event)"></wcc-counter>
152
+ */
153
+ export declare class WccEvent implements OnInit, OnDestroy {
154
+ wccEvent: string;
155
+ wccEmit: EventEmitter<any>;
156
+ private el;
157
+ private listener;
158
+ ngOnInit(): void;
159
+ ngOnDestroy(): void;
160
+ static ɵfac: i0.ɵɵFactoryDeclaration<WccEvent, never>;
161
+ static ɵdir: i0.ɵɵDirectiveDeclaration<WccEvent, "[wccEvent]", never, { "wccEvent": { "alias": "wccEvent"; "required": false; }; }, { "wccEmit": "wccEmit"; }, never, never, true, never>;
162
+ }
163
+ /**
164
+ * Event bridging directive: allows using camelCase event bindings on WCC elements.
165
+ *
166
+ * Without this directive, Angular devs must use kebab-case event names:
167
+ * <wcc-counter (count-changed)="onCount($event.detail)"></wcc-counter>
168
+ *
169
+ * With this directive, they can use camelCase (more Angular-idiomatic):
170
+ * <wcc-counter wccEvents (countChanged)="onCount($event.detail)"></wcc-counter>
171
+ *
172
+ * The directive listens for kebab-case CustomEvents from the WCC component
173
+ * and re-dispatches them with camelCase names so Angular's event binding picks them up.
174
+ *
175
+ * Event name conversion:
176
+ * 'count-changed' → dispatches 'countChanged'
177
+ * 'value-changed' → dispatches 'valueChanged'
178
+ * 'change' → dispatches 'change' (no conversion needed)
179
+ *
180
+ * Event discovery:
181
+ * - Auto: reads `static __events` from the WCC component class (set by codegen)
182
+ * - Manual: pass an explicit array via [wccEvents]="['count-changed', 'value-changed']"
183
+ *
184
+ * Note: $event is still the CustomEvent — use $event.detail to get the payload.
185
+ * This is consistent with how Angular handles all DOM events.
186
+ */
187
+ export declare class WccEvents implements OnInit, OnDestroy {
188
+ /** Optional explicit list of kebab-case event names to bridge */
189
+ wccEvents: string[] | '';
190
+ private el;
191
+ private listeners;
192
+ ngOnInit(): void;
193
+ private setupEvents;
194
+ ngOnDestroy(): void;
195
+ static ɵfac: i0.ɵɵFactoryDeclaration<WccEvents, never>;
196
+ static ɵdir: i0.ɵɵDirectiveDeclaration<WccEvents, "[wccEvents]", never, { "wccEvents": { "alias": "wccEvents"; "required": false; }; }, {}, never, never, true, never>;
197
+ }