sveld 0.22.4 → 0.22.5
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/lib/ComponentParser.js
CHANGED
|
@@ -485,7 +485,7 @@ class ComponentParser {
|
|
|
485
485
|
replace: false,
|
|
486
486
|
};
|
|
487
487
|
if (value === undefined)
|
|
488
|
-
return
|
|
488
|
+
return slot_props;
|
|
489
489
|
if (value[0]) {
|
|
490
490
|
const { type, expression, raw, start, end } = value[0];
|
|
491
491
|
if (type === "Text") {
|
|
@@ -606,9 +606,10 @@ class ComponentParser {
|
|
|
606
606
|
element: element,
|
|
607
607
|
description: event_description,
|
|
608
608
|
};
|
|
609
|
-
//
|
|
610
|
-
//
|
|
611
|
-
if
|
|
609
|
+
// Preserve detail type if it was explicitly set in @event tag
|
|
610
|
+
// Note: "null" is a valid explicit type (e.g., @event {null} eventname)
|
|
611
|
+
// Only skip if detail is truly undefined or the string "undefined"
|
|
612
|
+
if (event.detail !== undefined && event.detail !== "undefined") {
|
|
612
613
|
forwardedEvent.detail = event.detail;
|
|
613
614
|
}
|
|
614
615
|
this.events.set(eventName, forwardedEvent);
|
|
@@ -639,16 +640,9 @@ class ComponentParser {
|
|
|
639
640
|
if (slot_props[key].replace && slot_props[key].value !== undefined) {
|
|
640
641
|
slot_props[key].value = this.props.get(slot_props[key].value)?.type;
|
|
641
642
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
}
|
|
646
|
-
else if (typeof propValue === "string" && propValue.startsWith("{")) {
|
|
647
|
-
// If the value starts with {, it's a complex expression
|
|
648
|
-
// Use 'any' to avoid invalid TypeScript syntax
|
|
649
|
-
propValue = "any";
|
|
650
|
-
}
|
|
651
|
-
new_props.push(`${key}: ${propValue}`);
|
|
643
|
+
if (slot_props[key].value === undefined)
|
|
644
|
+
slot_props[key].value = "any";
|
|
645
|
+
new_props.push(`${key}: ${slot_props[key].value}`);
|
|
652
646
|
});
|
|
653
647
|
const formatted_slot_props = new_props.length === 0 ? "{}" : `{ ${new_props.join(", ")} }`;
|
|
654
648
|
return { ...slot, slot_props: formatted_slot_props };
|
|
@@ -168,6 +168,108 @@ function genEventDef(def) {
|
|
|
168
168
|
return detail;
|
|
169
169
|
return `CustomEvent<${detail}>`;
|
|
170
170
|
};
|
|
171
|
+
// Check if an event name is a standard DOM event that exists in WindowEventMap
|
|
172
|
+
const isStandardDomEvent = (eventName) => {
|
|
173
|
+
// Standard DOM events that should use WindowEventMap
|
|
174
|
+
const standardEvents = new Set([
|
|
175
|
+
// Mouse events
|
|
176
|
+
"click",
|
|
177
|
+
"dblclick",
|
|
178
|
+
"mousedown",
|
|
179
|
+
"mouseup",
|
|
180
|
+
"mousemove",
|
|
181
|
+
"mouseover",
|
|
182
|
+
"mouseout",
|
|
183
|
+
"mouseenter",
|
|
184
|
+
"mouseleave",
|
|
185
|
+
"contextmenu",
|
|
186
|
+
"wheel",
|
|
187
|
+
// Keyboard events
|
|
188
|
+
"keydown",
|
|
189
|
+
"keyup",
|
|
190
|
+
"keypress",
|
|
191
|
+
// Form events
|
|
192
|
+
"submit",
|
|
193
|
+
"change",
|
|
194
|
+
"input",
|
|
195
|
+
"focus",
|
|
196
|
+
"blur",
|
|
197
|
+
"focusin",
|
|
198
|
+
"focusout",
|
|
199
|
+
"reset",
|
|
200
|
+
"select",
|
|
201
|
+
// Touch events
|
|
202
|
+
"touchstart",
|
|
203
|
+
"touchend",
|
|
204
|
+
"touchmove",
|
|
205
|
+
"touchcancel",
|
|
206
|
+
// Drag events
|
|
207
|
+
"drag",
|
|
208
|
+
"dragstart",
|
|
209
|
+
"dragend",
|
|
210
|
+
"dragover",
|
|
211
|
+
"dragenter",
|
|
212
|
+
"dragleave",
|
|
213
|
+
"drop",
|
|
214
|
+
// Pointer events
|
|
215
|
+
"pointerdown",
|
|
216
|
+
"pointerup",
|
|
217
|
+
"pointermove",
|
|
218
|
+
"pointerover",
|
|
219
|
+
"pointerout",
|
|
220
|
+
"pointerenter",
|
|
221
|
+
"pointerleave",
|
|
222
|
+
"pointercancel",
|
|
223
|
+
"gotpointercapture",
|
|
224
|
+
"lostpointercapture",
|
|
225
|
+
// Media events
|
|
226
|
+
"play",
|
|
227
|
+
"pause",
|
|
228
|
+
"ended",
|
|
229
|
+
"volumechange",
|
|
230
|
+
"timeupdate",
|
|
231
|
+
"loadeddata",
|
|
232
|
+
"loadedmetadata",
|
|
233
|
+
"canplay",
|
|
234
|
+
"canplaythrough",
|
|
235
|
+
"seeking",
|
|
236
|
+
"seeked",
|
|
237
|
+
"playing",
|
|
238
|
+
"waiting",
|
|
239
|
+
"stalled",
|
|
240
|
+
"suspend",
|
|
241
|
+
"abort",
|
|
242
|
+
"error",
|
|
243
|
+
"emptied",
|
|
244
|
+
"ratechange",
|
|
245
|
+
"durationchange",
|
|
246
|
+
"loadstart",
|
|
247
|
+
"progress",
|
|
248
|
+
"loadend",
|
|
249
|
+
// Animation/Transition events
|
|
250
|
+
"animationstart",
|
|
251
|
+
"animationend",
|
|
252
|
+
"animationiteration",
|
|
253
|
+
"animationcancel",
|
|
254
|
+
"transitionstart",
|
|
255
|
+
"transitionend",
|
|
256
|
+
"transitionrun",
|
|
257
|
+
"transitioncancel",
|
|
258
|
+
// Other events
|
|
259
|
+
"scroll",
|
|
260
|
+
"resize",
|
|
261
|
+
"load",
|
|
262
|
+
"unload",
|
|
263
|
+
"beforeunload",
|
|
264
|
+
"cut",
|
|
265
|
+
"copy",
|
|
266
|
+
"paste",
|
|
267
|
+
"compositionstart",
|
|
268
|
+
"compositionupdate",
|
|
269
|
+
"compositionend",
|
|
270
|
+
]);
|
|
271
|
+
return standardEvents.has(eventName);
|
|
272
|
+
};
|
|
171
273
|
if (def.events.length === 0)
|
|
172
274
|
return EMPTY_EVENTS;
|
|
173
275
|
const events_map = def.events
|
|
@@ -181,18 +283,26 @@ function genEventDef(def) {
|
|
|
181
283
|
eventType = createDispatchedEvent(event.detail);
|
|
182
284
|
}
|
|
183
285
|
else {
|
|
184
|
-
// For forwarded events,
|
|
185
|
-
// If element starts with uppercase, it's a component, so treat as CustomEvent
|
|
186
|
-
// Also check if the forwarded event has detail type information preserved
|
|
286
|
+
// For forwarded events, determine the type based on @event JSDoc and element/event type
|
|
187
287
|
const elementName = typeof event.element === "string" ? event.element : event.element.name;
|
|
188
288
|
const isComponent = elementName && /^[A-Z]/.test(elementName);
|
|
189
|
-
const
|
|
190
|
-
if
|
|
289
|
+
const isStandardEvent = !isComponent || isStandardDomEvent(event.name);
|
|
290
|
+
// Check if there's an explicit non-null detail type from @event JSDoc
|
|
291
|
+
// Note: detail="null" on standard DOM events is treated as "not explicitly typed"
|
|
292
|
+
// because @event click (without {type}) defaults to null but shouldn't override WindowEventMap
|
|
293
|
+
const hasExplicitNonNullDetail = event.detail !== undefined && event.detail !== "undefined" && !(event.detail === "null" && isStandardEvent);
|
|
294
|
+
if (hasExplicitNonNullDetail) {
|
|
295
|
+
// If @event tag explicitly provides a non-null detail type, always use it (highest priority)
|
|
191
296
|
eventType = createDispatchedEvent(event.detail);
|
|
192
297
|
}
|
|
193
|
-
else {
|
|
298
|
+
else if (isStandardEvent) {
|
|
299
|
+
// Standard DOM event (native element or standard event name) without explicit type
|
|
194
300
|
eventType = `${mapEvent()}["${event.name}"]`;
|
|
195
301
|
}
|
|
302
|
+
else {
|
|
303
|
+
// Custom event from component with no explicit type or explicit null
|
|
304
|
+
eventType = event.detail === "null" ? createDispatchedEvent("null") : createDispatchedEvent();
|
|
305
|
+
}
|
|
196
306
|
}
|
|
197
307
|
return `${description}${clampKey(event.name)}: ${eventType};\n`;
|
|
198
308
|
})
|