Skip to content

Commit 2eb9a98

Browse files
committed
useOn: accept event names as-is
1 parent 865db3a commit 2eb9a98

File tree

3 files changed

+24
-34
lines changed

3 files changed

+24
-34
lines changed

packages/qwik/src/core/shared/utils/event-names.ts

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -41,40 +41,21 @@ export const isHtmlAttributeAnEventName = (name: string): boolean => {
4141
);
4242
};
4343

44-
/**
45-
* Converts a JSX event property to an HTML attribute. Examples:
46-
*
47-
* - OnClick$ -> on:click
48-
* - On-DOMContentLoaded$ -> on:-d-o-m-content-loaded
49-
* - On-CustomEvent$ -> on:-custom-event
50-
*/
5144
export function jsxEventToHtmlAttribute(jsxEvent: string): string | null {
5245
if (jsxEvent.endsWith(EVENT_SUFFIX)) {
5346
const [prefix, idx] = getEventScopeDataFromJsxEvent(jsxEvent);
5447

5548
if (idx !== -1) {
56-
return createEventName(jsxEvent, prefix, idx, jsxEvent.length - 1 /* don't include `$` */);
49+
const name = jsxEvent.slice(idx, -1);
50+
return createEventName(name, prefix);
5751
}
5852
}
5953
return null; // Return null if not matching expected format
6054
}
6155

62-
export function createEventName(
63-
event: string,
64-
prefix: EventNameHtmlScope,
65-
startIdx = 0,
66-
endIdx = event.length
67-
): string {
68-
const eventName = jsxEventToEventName(event, startIdx, endIdx);
69-
return prefix + fromCamelToKebabCase(eventName);
70-
}
71-
72-
export function jsxEventToEventName(jsxEvent: string, startIdx: number, endIdx: number): string {
73-
const chunk = jsxEvent.substring(startIdx, endIdx);
74-
if (chunk === 'DOMContentLoaded') {
75-
return '-d-o-m-content-loaded';
76-
}
77-
return chunk.toLowerCase();
56+
export function createEventName(event: string, prefix: EventNameHtmlScope): string {
57+
const eventName = event === 'DOMContentLoaded' ? '-d-o-m-content-loaded' : event.toLowerCase();
58+
return prefix + eventName;
7859
}
7960

8061
export function getEventScopeDataFromJsxEvent(eventName: string): [EventNameHtmlScope, number] {

packages/qwik/src/core/tests/render-api.spec.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ const ManyEventsComponent = component$(() => {
8383
'focus',
8484
inlinedQrl(() => {}, 's_useOnFocus')
8585
);
86+
useOn(
87+
'-My-Custom',
88+
inlinedQrl(() => {}, 's_useOnMyCustom')
89+
);
8690
return (
8791
<div>
8892
<button
@@ -91,7 +95,11 @@ const ManyEventsComponent = component$(() => {
9195
>
9296
click
9397
</button>
94-
<button onClick$={inlinedQrl(() => {}, 's_click2')} onBlur$={inlinedQrl(() => {}, 's_blur1')}>
98+
<button
99+
onClick$={inlinedQrl(() => {}, 's_click2')}
100+
onBlur$={inlinedQrl(() => {}, 's_blur1')}
101+
onAnother-custom$={inlinedQrl(() => {}, 's_anotherCustom1')}
102+
>
95103
click
96104
</button>
97105
</div>
@@ -491,7 +499,7 @@ describe('render api', () => {
491499
qwikLoader: 'module',
492500
});
493501
expect(result.html).toContain(
494-
'(window.qwikevents||(window.qwikevents=[])).push("focus", "click", "dblclick", "blur")'
502+
'(window.qwikevents||(window.qwikevents=[])).push("focus", "-my-custom", "click", "dblclick", "another-custom", "blur")'
495503
);
496504
});
497505
});

packages/qwik/src/core/use/use-on.unit.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// oxlint-disable no-unused-vars
12
import { assertType, describe, expectTypeOf, test } from 'vitest';
23
import { useOn, type EventQRL } from './use-on';
34
import { $, type QRL, type QrlReturn } from '../shared/qrl/qrl.public';
@@ -13,15 +14,15 @@ describe('types', () => {
1314
const wrong1 = (ev: MouseEvent, elem: Element, extra: string) => 'hello';
1415
const wrong2 = (ev: boolean) => 'hello';
1516

16-
expectTypeOf<undefined>().toMatchTypeOf<EventQRL>();
17-
expectTypeOf<QRL<typeof cb0>>().toMatchTypeOf<EventQRL>();
18-
expectTypeOf<QRL<typeof cb1>>().toMatchTypeOf<EventQRL>();
19-
expectTypeOf<QRL<typeof cb2>>().toMatchTypeOf<EventQRL>();
17+
expectTypeOf<undefined>().toExtend<EventQRL>();
18+
expectTypeOf<QRL<typeof cb0>>().toExtend<EventQRL>();
19+
expectTypeOf<QRL<typeof cb1>>().toExtend<EventQRL>();
20+
expectTypeOf<QRL<typeof cb2>>().toExtend<EventQRL>();
2021

21-
expectTypeOf<QRL<typeof cbAny>>().toMatchTypeOf<EventQRL>();
22+
expectTypeOf<QRL<typeof cbAny>>().toExtend<EventQRL>();
2223

23-
expectTypeOf<QRL<typeof wrong1>>().not.toMatchTypeOf<EventQRL>();
24-
expectTypeOf<QRL<typeof wrong2>>().not.toMatchTypeOf<EventQRL>();
24+
expectTypeOf<QRL<typeof wrong1>>().not.toExtend<EventQRL>();
25+
expectTypeOf<QRL<typeof wrong2>>().not.toExtend<EventQRL>();
2526
});
2627

2728
test('inferring', () => () => {
@@ -35,7 +36,7 @@ describe('types', () => {
3536
expectTypeOf(called.ev).not.toBeAny();
3637
expectTypeOf(called.el).not.toBeAny();
3738
assertType<Element | undefined>(called.el);
38-
expectTypeOf<Event>().toMatchTypeOf(called.ev);
39+
expectTypeOf(called.ev).toExtend<Event>();
3940
});
4041

4142
test('useOn', () => () => {

0 commit comments

Comments
 (0)