Skip to content

Commit

Permalink
Merge pull request #144 from grucloud/fix-event-types
Browse files Browse the repository at this point in the history
Fix event types
  • Loading branch information
FredericHeem authored Dec 19, 2024
2 parents 34c21c5 + 6deb5e5 commit 2c43b56
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ export default (context: Context) => {
name: "check",
required: true,
value: inputState,
oninput: (event: any) => (inputState.val = event.target.value),
oninput: ({ target }: { target: HTMLInputElement }) =>
(inputState.val = target.value),
})
)
),
Expand Down
7 changes: 5 additions & 2 deletions bau-ui/radioButtonGroup/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ declare module "@grucloud/bau-ui/radioButtonGroup" {
export type RadioButtonGroupProps = {
name: string;
value?: any;
oninput?: (event) => any;
oninput?: ({ target }: { target: HTMLInputElement }) => void;
radios: RadioItem[];
} & DefaultDesignProps;

type Component = import("../bau-ui").Component<RadioButtonGroupProps>;
type Component = import("../bau-ui").Component<
RadioButtonGroupProps,
HTMLInputElement
>;

export default function (context: any, option?: ComponentOption): Component;
}
70 changes: 19 additions & 51 deletions bau/bau.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,63 +42,32 @@ export type BindAttributeFunc<TElement extends HTMLElement> = (input: {
element: TElement;
}) => Primitive | Function;

type EventListener = (
event:
| InputEvent
| SubmitEvent
| Event
| AnimationEvent
| BeforeUnloadEvent
| BlobEvent
| ClipboardEvent
| CloseEvent
| CompositionEvent
| DeviceMotionEvent
| DeviceOrientationEvent
| DragEvent
| ErrorEvent
| FocusEvent
| FontFaceSetLoadEvent
| FormDataEvent
| GamepadEvent
| HashChangeEvent
| IDBVersionChangeEvent
| InputEvent
| KeyboardEvent
| MessageEvent
| MouseEvent
| OfflineAudioCompletionEvent
| PageTransitionEvent
| PaymentRequestUpdateEvent
| PointerEvent
| PopStateEvent
| ProgressEvent
| RTCDataChannelEvent
| RTCPeerConnectionIceEvent
| StorageEvent
| SubmitEvent
| TouchEvent
| TrackEvent
| TransitionEvent
| UIEvent
| WebGLContextEvent
| WheelEvent
) => any;

export type Props<TElement extends HTMLElement> = {
readonly [key: string]:
| PropValue
| EventListener
| StateView<PropValue>
| BindAttributeFunc<TElement>
| DerivedProp;
};

// This helper will replace the Event parameter of an event handler
// with something else (technically it takes the union of the Event and ReplaceWith)
type ReplaceEventHandlerParameter<EventHandler, ReplaceWith> =
EventHandler extends (...args: infer Params) => infer R
? (...args: {[K in keyof Params]: Params[K] extends Event ? Params[K] & ReplaceWith : Params[K]}) => R
: never;

export type PropsHTMLElement<TElement extends HTMLElement> = {
readonly [key in keyof TElement]?:
| PropValue
| StateView<PropValue>
| BindAttributeFunc<TElement>;
readonly [
key in keyof TElement as key extends `on${string}`
? key
: never
]?: key extends 'oninput'
// we use InputEvent for 'oninput'
// this is not 100% type correct, but it is convenient and backwards compatible
? ReplaceEventHandlerParameter<ReplaceEventHandlerParameter<TElement[key], { target: TElement}>, InputEvent>
// for all other events (and also for oninput) we set the target to TElement
: ReplaceEventHandlerParameter<TElement[key], { target: TElement}>
};

export type PropsLifecycle<TElement extends HTMLElement> = {
Expand All @@ -112,9 +81,8 @@ export type PropsLifecycle<TElement extends HTMLElement> = {
};

export type PropsAll<TElement extends HTMLElement> =
| PropsHTMLElement<TElement>
| PropsLifecycle<TElement>
| Props<TElement>
PropsLifecycle<TElement>
| (Props<TElement> & PropsHTMLElement<TElement>)
| ChildDom;

export type BindElementFunc = (input?: {
Expand Down
28 changes: 17 additions & 11 deletions bau/examples/bau-ts-test/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,7 @@ const TestDerived = () => {
input({
placeholder: "Enter username",
value: inputState,
oninput: ({ target }: { target: HTMLInputElement }) =>
(inputState.val = target.value),
oninput: ({ target }) => (inputState.val = target.value),
}),
button(
{
Expand All @@ -532,8 +531,7 @@ const TestDerivedSideEffect = () => {
input({
placeholder: "Enter username",
value: inputState,
oninput: ({ target }: { target: HTMLInputElement }) =>
(inputState.val = target.value),
oninput: ({ target }) => (inputState.val = target.value),
})
);
};
Expand Down Expand Up @@ -753,8 +751,7 @@ const TestInputOninput = () => {
input({
placeholder: "Enter username",
value: inputState,
oninput: ({ target }: { target: HTMLInputElement }) =>
(inputState.val = target.value),
oninput: ({ target }) => (inputState.val = target.value),
}),
button(
{
Expand All @@ -776,8 +773,7 @@ const TestInputSearch = () => {
type: "search",
placeholder: "Search...",
value: inputState,
oninput: ({ target }: { target: HTMLInputElement }) =>
(inputState.val = target.value),
oninput: ({ target }) => (inputState.val = target.value),
}),
button(
{
Expand Down Expand Up @@ -820,7 +816,7 @@ const TestEventHandlingKeyUp = () => {
input({
type: "search",
size: 25,
onkeyup: ({ target, key }: { key: string; target: HTMLInputElement }) => {
onkeyup: ({ target, key }) => {
if (key == "Enter") {
alert(target.value);
}
Expand All @@ -838,8 +834,7 @@ const TestInputCheckboxOninput = () => {
input({
type: "checkbox",
checked: checkedState,
oninput: ({ target }: { target: HTMLInputElement }) =>
(checkedState.val = target.checked),
oninput: ({ target }) => (checkedState.val = target.checked),
}),
div("Is checked: ", () => (checkedState.val ? "Checked" : "Not Checked"))
);
Expand Down Expand Up @@ -1044,5 +1039,16 @@ const App = ({}) => {
);
};

input({
type: "text",
oninput: (event) => {
console.log(event.data);
console.log(event.target);
},
onchange: (event) => {
console.log(event.target.value);
},
});

const app = document.getElementById("app");
app?.replaceChildren(App({}));
3 changes: 1 addition & 2 deletions doc/BauDerive.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ const TestDerived = () => {
input({
placeholder: "Enter username",
value: inputState,
oninput: ({ target }: { target: HTMLInputElement }) =>
(inputState.val = target.value),
oninput: ({ target }) => (inputState.val = target.value),
}),
button(
{
Expand Down
6 changes: 2 additions & 4 deletions doc/BauEventHandling.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ const TestInputOninput = () => {
input({
placeholder: "Enter username",
value: inputState,
oninput: ({ target }: { target: HTMLInputElement }) =>
(inputState.val = target.value),
oninput: ({ target }) => (inputState.val = target.value),
}),
button(
{
Expand Down Expand Up @@ -149,8 +148,7 @@ const TestInputCheckboxOninput = () => {
input({
type: "checkbox",
checked: checkedState,
oninput: ({ target }: { target: HTMLInputElement }) =>
(checkedState.val = target.checked),
oninput: ({ target }) => (checkedState.val = target.checked),
}),
div("Is checked: ", () => (checkedState.val ? "Checked" : "Not Checked"))
);
Expand Down

0 comments on commit 2c43b56

Please sign in to comment.