fix: better type inference for MediaQuery (#180)

This commit is contained in:
Thomas Klein 2019-10-13 10:49:55 +02:00 committed by Juan Picado @jotadeveloper
parent d1b3e6e3b5
commit e0e7c07bce

View File

@ -1,4 +1,4 @@
import { css } from 'emotion';
import { css, Interpolation } from 'emotion';
export const breakpoints = {
small: 576,
@ -8,26 +8,31 @@ export const breakpoints = {
xlarge: 1275,
};
type Sizes = keyof typeof breakpoints;
type Breakpoints = typeof breakpoints;
type Sizes = keyof Breakpoints;
type MediaQuery = {
[key in Sizes]: (cls: any) => string;
type MediaQuery<T> = {
[P in keyof T]: (args: Interpolation, key?: P) => string;
};
const mq: MediaQuery = Object.keys(breakpoints).reduce(
(accumulator, label) => {
const prefix = typeof breakpoints[label] === 'string' ? '' : 'min-width:';
const suffix = typeof breakpoints[label] === 'string' ? '' : 'px';
accumulator[label] = cls =>
css`
@media (${prefix + breakpoints[label] + suffix}) {
${cls};
}
`;
return accumulator;
},
// eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion
{} as MediaQuery
);
function constructMQ(breakpoint: Sizes, args: Interpolation): string {
const label = breakpoints[breakpoint];
const prefix = typeof label === 'string' ? '' : 'min-width:';
const suffix = typeof label === 'string' ? '' : 'px';
return css`
@media (${prefix + breakpoints[breakpoint] + suffix}) {
${args};
}
`;
}
const mq: MediaQuery<Breakpoints> = {
small: (args, b = 'small') => constructMQ(b, args),
large: (args, b = 'large') => constructMQ(b, args),
container: (args, b = 'container') => constructMQ(b, args),
medium: (args, b = 'medium') => constructMQ(b, args),
xlarge: (args, b = 'xlarge') => constructMQ(b, args),
};
export default mq;