Skip to content

Commit

Permalink
chore(suite): improve the typing of the pickAndPrepareFrameProps() an…
Browse files Browse the repository at this point in the history
…d fix type / code error
  • Loading branch information
vojtatranta committed Feb 6, 2025
1 parent 7d99f54 commit 38f269b
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 13 deletions.
2 changes: 1 addition & 1 deletion packages/components/src/components/Icon/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,8 @@ export const Icon = forwardRef(
onClick={onClick ? handleClick : undefined}
className={className}
ref={ref}
$cursor={cursor ?? (onClick ? 'pointer' : undefined)}
{...frameProps}
$cursor={cursor ?? (onClick ? 'pointer' : undefined)}
>
<SVG
tabIndex={onClick ? 0 : undefined}
Expand Down
59 changes: 59 additions & 0 deletions packages/components/src/utils/frameProps.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { makePropsTransient } from './transientProps';

describe('frameprops', () => {
describe('type tests', () => {
it('should return the same keys just with the $ prefix as type', () => {
const result: {
$a: 1;
$b: 2;
} = makePropsTransient({ a: 1, b: 2 } as const);
expect(result).toEqual({
$a: 1,
$b: 2,
});
});

it('should correctly be able to pick individual key', () => {
const result: {
$a: 1;
$b: 2;
} = makePropsTransient({ a: 1, b: 2 } as const);

const a = result.$a;
expect(a).toEqual(1);
});

it('should throw a type error when the resulting object is not assigned to a variable with a $ prefix', () => {
// @ts-expect-error: here should be $ prefix for the key
const result: {
a: 1;
$b: 2;
} = makePropsTransient({ a: 1, b: 2 } as const);
expect(result).toEqual({
$a: 1,
$b: 2,
});
});
it('should throw a type error when trying to get the key that is not specified in the argument object', () => {
// @ts-expect-error: c is not a key of the object
const result: {
$c: 1;
} = makePropsTransient({ a: 1, b: 2 } as const);
expect(result).toEqual({
$a: 1,
$b: 2,
});
});

it('should throw a type error when trying to access a key without a $ prefix', () => {
const result: {
$a: 1;
$b: 2;
} = makePropsTransient({ a: 1, b: 2 } as const);

// @ts-expect-error: here should be $ prefix for the key
const { a } = result;
expect(a).toEqual(undefined);
});
});
});
24 changes: 12 additions & 12 deletions packages/components/src/utils/frameProps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ type Position = {
left?: string | number;
};

const cursors = ['pointer', 'help', 'default', 'not-allowed'] as const;
const cursors = ['pointer', 'help', 'default', 'not-allowed', 'inherit'] as const;
type Cursor = (typeof cursors)[number];

export type FrameProps = {
Expand All @@ -83,21 +83,21 @@ type TransientFrameProps = TransientProps<FrameProps>;
const getValueWithUnit = (value: string | number) =>
typeof value === 'number' ? `${value}px` : value;

export const pickAndPrepareFrameProps = (
props: Record<string, any>,
allowedFrameProps: Array<FramePropsKeys>,
convertToTransient = true,
export const pickAndPrepareFrameProps = <
TProps extends { [K in FramePropsKeys]?: FrameProps[K] },
KFP extends FramePropsKeys[],
>(
props: TProps,
allowedFrameProps: KFP,
) => {
const selectedProps = allowedFrameProps.reduce(
const selectedProps = allowedFrameProps.reduce<{
[value in KFP[number]]: TProps[value];
}>(
(acc, item) => ({ ...acc, [item]: props[item] }),
{},
{} as { [value in KFP[number]]: TProps[value] },
);

if (convertToTransient) {
return makePropsTransient(selectedProps);
}

return selectedProps;
return makePropsTransient(selectedProps);
};

export const withFrameProps = ({
Expand Down
28 changes: 28 additions & 0 deletions packages/components/src/utils/transientProps.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { makePropsTransient } from './transientProps';

describe('transientProps', () => {
describe('type tests', () => {
it('should return the same keys just with the $ prefix as type', () => {
const result: {
$a: 1;
$b: 2;
} = makePropsTransient({ a: 1, b: 2 } as const);
expect(result).toEqual({
$a: 1,
$b: 2,
});
});

it("should should throw an a type error when there isn't a property with a $ prefix", () => {
// @ts-expect-error: here should be $ prefixes for the keys
const result: {
a: 1;
b: 2;
} = makePropsTransient({ a: 1, b: 2 } as const);
expect(result).toEqual({
$a: 1,
$b: 2,
});
});
});
});

0 comments on commit 38f269b

Please sign in to comment.