Skip to content

Commit

Permalink
Cleanup hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandrHoroshih committed Apr 8, 2024
1 parent 3de2e9b commit 0141018
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 11 deletions.
10 changes: 8 additions & 2 deletions public-types/reflect.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ type UseUnitConfig = Parameters<typeof useUnit>[1];
type UnbindableProps = 'key' | 'ref';

type Hooks<Props> = {
mounted?: EventCallable<Props> | EventCallable<void> | ((props: Props) => unknown);
unmounted?: EventCallable<void> | (() => unknown);
mounted?:
| EventCallable<Props extends infer HookArg ? HookArg : never>
| EventCallable<void>
| ((props: Props) => unknown);
unmounted?:
| EventCallable<Props extends infer HookArg ? HookArg : never>
| EventCallable<void>
| ((props: Props) => unknown);
};

/**
Expand Down
12 changes: 9 additions & 3 deletions src/core/reflect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,14 @@ export function reflectFactory(context: Context) {
const eventsProps = context.useUnit(events as any, config.useUnitConfig);
const functionProps = useBoundFunctions(functions);

const finalProps: any = {};

if (ref) {
finalProps.ref = ref;
}

const elementProps: Props = Object.assign(
{ ref },
finalProps,
storeProps,
eventsProps,
data,
Expand All @@ -50,12 +56,12 @@ export function reflectFactory(context: Context) {
const hooks: Hooks<Props> = Object.assign({}, functionsHooks, eventsHooks);

if (hooks.mounted) {
hooks.mounted(props);
hooks.mounted(elementProps);
}

return () => {
if (hooks.unmounted) {
hooks.unmounted();
hooks.unmounted(elementProps);
}
};
}, [eventsHooks, functionsHooks]);
Expand Down
2 changes: 1 addition & 1 deletion src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export type Hook<Props> =

export type Hooks<Props> = {
mounted?: Hook<Props>;
unmounted?: Hook<void>;
unmounted?: Hook<Props>;
};

export type UseUnitConifg = Parameters<typeof useUnit>[1];
4 changes: 2 additions & 2 deletions src/no-ssr/reflect.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ describe('hooks', () => {
);

expect($lastProps.getState()).toBeNull();
expect(scope.getState($lastProps)).toStrictEqual({
expect(scope.getState($lastProps)).toEqual({
value: 'test',
'data-testid': 'name',
});
Expand Down Expand Up @@ -475,7 +475,7 @@ describe('hooks', () => {
);

expect($lastProps.getState()).toBeNull();
expect(scope.getState($lastProps)).toStrictEqual({
expect(scope.getState($lastProps)).toEqual({
value: 'test',
'data-testid': 'name',
});
Expand Down
43 changes: 40 additions & 3 deletions type-tests/types-reflect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ function localize(value: string): unknown {
type Props = { loading: boolean };

const mounted = createEvent();
const unmounted = createEvent();

const Foo: FC<Props> = (props) => <></>;

Expand All @@ -390,7 +391,7 @@ function localize(value: string): unknown {
bind: {
loading: $loading,
},
hooks: { mounted },
hooks: { mounted, unmounted },
});
}

Expand All @@ -399,6 +400,7 @@ function localize(value: string): unknown {
type Props = { loading: boolean };

const mounted = createEvent<Props>();
const unmounted = createEvent<Props>();

const Foo: FC<Props> = (props) => <></>;

Expand All @@ -409,19 +411,54 @@ function localize(value: string): unknown {
bind: {
loading: $loading,
},
hooks: { mounted },
hooks: { mounted, unmounted },
});
}

// should error if mounted event doesn't satisfy component props
{
const mounted = createEvent<{ foo: string }>();
const unmounted = createEvent<{ foo: string }>();

const Foo: FC<{ bar: number }> = () => null;

const Bar = reflect({
view: Foo,
// @ts-expect-error
hooks: { mounted },
hooks: { mounted, unmounted },
});
}

// reflect supports partial match of mounted event and component props
{
const mounted = createEvent<{ foo: string }>();
const unmounted = createEvent<{ foo: string }>();

const Foo: FC<{ foo: string; bar: number }> = () => null;

const Bar = reflect({
view: Foo,
bind: {
foo: 'foo',
bar: 42,
},
hooks: { mounted, unmounted },
});
}

// reflect supports partial match of mounted callback and component props
{
const mounted = (args: { foo: string }) => {};
const unmounted = (args: { foo: string }) => {};

const Foo: FC<{ foo: string; bar: number }> = () => null;

const Bar = reflect({
view: Foo,
bind: {
foo: 'foo',
bar: 42,
},
hooks: { mounted, unmounted },
});
}

0 comments on commit 0141018

Please sign in to comment.